鏈表(二):單向鏈表


一、什么是單向鏈表

在動態分配內存空間時,最常使用的就是“單向鏈表”(Single Linked List)。一個單向鏈表節點基本上是由兩個元素,即數據字段和指針所組成,而指針將會指向下一個元素在內存中的位置,如下圖所示:

在“單向鏈表”中,第一個節點是“鏈表頭指針”,指向最后一個節點的指針設為NULL,表示它是“鏈表尾”,不指向任何地方。例如列表A={a、b、c、d、x},其單向鏈表的數據結構如下圖所示:

由於單向鏈表中所有節點都知道節點本身的下一個節點在哪里,但是對於前一個節點卻沒有辦法知道,所以在單向鏈表的各種操作中,“鏈表頭指針”就顯得相當重要,只要存在鏈表頭指針,就可以遍歷整個鏈表,進行加入和刪除節點等操作。

注意:除非必要,否則不可移動鏈表頭指針。

通常在其他程序設計語言中,如C或C++語言,是以指針(pointer)類型來處理鏈表類型的數據結構。由於在C#程序設計語言中沒有指針類型,因此可以把鏈表聲明為類(class)。例如要模擬鏈表中的節點,必須聲明如下的Node類,這里使用泛型:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SingleLinkedListDemo
{
    /// <summary>
    /// 鏈表節點類
    /// </summary>
    public class Node<T>
    {
        /// <summary>
        /// 數據字段
        /// </summary>
        public T Data { get; set; }

        /// <summary>
        /// 指針 指向下一個元素
        /// </summary>
        public Node<T> Next { get; set; }

        /// <summary>
        /// 無參構造函數
        /// </summary>
        public Node()
        {
            // 賦默認值
            this.Data = default(T);
            this.Next = null;
        }

        /// <summary>
        /// 只傳遞數據字段的構造函數,指針默認為null
        /// </summary>
        /// <param name="value"></param>
        public Node(T value)
        {
            this.Data = value;
            this.Next = null;
        }

        /// <summary>
        /// 同時傳遞數據和指針的構造函數
        /// </summary>
        /// <param name="value"></param>
        /// <param name="next"></param>
        public Node(T value,Node<T> next)
        {
            this.Data = value;
            this.Next = next;
        }

        /// <summary>
        /// 只傳遞指針的構造函數
        /// </summary>
        /// <param name="next"></param>
        public Node(Node<T> next)
        {
            this.Next = next;
        }
    }
}

接着可以聲明鏈表SingleLinkedList類,該類定義兩個Node<T>類型的節點指針,分別指向鏈表的第一個節點和最后一個節點:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SingleLinkedListDemo
{
    public class SingleLinkedList<T>
    {
        /// <summary>
        /// 頭節點
        /// </summary>
        private Node<T> HeadNode;

        /// <summary>
        /// 尾節點
        /// </summary>
        private Node<T> LastNode;

        // 定義類中其它方法,增加節點、刪除節點、移動節點等
    }
}

如果鏈表中的節點不只記錄單一數值,例如每一個節點除了有指向下一個節點的指針字段外,還包括學生的姓名、學號、成績,則其鏈表如下圖所示:

如果是這種鏈表,我們可以先定義一個Student類,里面包括姓名、學號、成績,然后Node節點里面使用泛型Node<Student>。下面我們以學生為例講解如何創建一個單向鏈表。

1、建立單向鏈表

現在我們使用C#語言的鏈表處理以下學生的成績問題。

首先我們必須聲明節點的數據類型,讓每一個節點包含一個數據,並且包含指向下一個節點的指針,使所有的數據都能被串在一起形成一個列表結構,最終鏈表如下圖所示:

下面我們詳細說明建立上圖所示的單向鏈表的步驟:

1、建立一個新的節點,如圖所示:

2、這時鏈表是空的,所以講鏈表的first即last指針字段都指向新創建的節點newNode,如圖所示:

3、建立另外一個新的節點,如圖所示:

4、將上面的兩個節點串起來,使用下面的代碼:

last.next=newNode;
last=newNode;

如圖所示:

5、重復上面的3、4步驟,將所有的節點都連接起來,最終鏈表結構如圖所示:

由於列表中所有節點都知道節點本身的下一個節點在哪里,但是對於前一個節點卻沒有辦法知道,所以“頭節點”就顯得非常重要。

無論如何,只要有頭節點存在,就可以對整個列表進行遍歷、加入、刪除、查找等操作。而之前建立的節點若沒有串接起來就會形成無人管理的節點,並一直占用內存空間。因此在建立列表時必須有一個列表指針指向頭節點,並且在沒有必要的情況下不可以移動列表首指針。

我們可以在程序中會聲明Node類和SignleLinkedList類,在SignleLinkedList類中,定義了兩個Node類型的節點指針,分別指向鏈表的第一個節點和最后一個節點。另外,該類中還需要聲明下面的兩個方法:

方法名稱 功能描述
public bool IsEmpty() 用來判斷當前的鏈表是否為空鏈表
public void Add(T item) 用來將指定的節點插入到當前的鏈表

下面我們以一個具體的例子來講解如何創建一個單向鏈表。需求如下:

設計一個C#程序,可以讓用戶輸入數據來添加學生數據節點,以建立一個單向鏈表。一共輸入5位學生的成績來建立單向鏈表,然后遍歷單向鏈表中的每一個節點來打印輸出學生的信息。

我們先建立Node節點類,這里使用泛型,利於擴展:

namespace SingleLinkedListDemo
{
    /// <summary>
    /// 鏈表節點類
    /// </summary>
    public class Node<T>
    {
        /// <summary>
        /// 數據字段
        /// </summary>
        public T Data { get; set; }

        /// <summary>
        /// 指針 指向下一個元素
        /// </summary>
        public Node<T> Next { get; set; }

        /// <summary>
        /// 無參構造函數
        /// </summary>
        public Node()
        {
            // 賦默認值
            this.Data = default(T);
            this.Next = null;
        }

        /// <summary>
        /// 只傳遞數據字段的構造函數,指針默認為null
        /// </summary>
        /// <param name="value"></param>
        public Node(T value)
        {
            this.Data = value;
            this.Next = null;
        }

        /// <summary>
        /// 同時傳遞數據和指針的構造函數
        /// </summary>
        /// <param name="value"></param>
        /// <param name="next"></param>
        public Node(T value,Node<T> next)
        {
            this.Data = value;
            this.Next = next;
        }

        /// <summary>
        /// 只傳遞指針的構造函數
        /// </summary>
        /// <param name="next"></param>
        public Node(Node<T> next)
        {
            this.Next = next;
        }
    }
}

我們創建一個Student類,用來存放學生信息:

namespace SingleLinkedListDemo
{
    /// <summary>
    /// 學生類
    /// </summary>
    public class Student
    {
        /// <summary>
        /// 學號
        /// </summary>
        public int Number { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 成績
        /// </summary>
        public int Score { get; set; }

        public Student(int number,string name,int score)
        {
            Number = number;
            Name = name;
            Score = score;
        }
    }
}

最后創建SignleLinkedList類,代碼如下:

using System.Collections.Generic;

namespace SingleLinkedListDemo
{
    /// <summary>
    /// 單向鏈表類
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SingleLinkedList<T>
    {
        /// <summary>
        /// 存放所有鏈表節點的集合
        /// </summary>
        public List<Node<T>> ListNode { get; set; }

        /// <summary>
        /// 構造函數
        /// </summary>
        public SingleLinkedList()
        {
            ListNode = new List<Node<T>>();
        }

        /// <summary>
        /// 頭節點
        /// </summary>
        private Node<T> HeadNode;

        /// <summary>
        /// 尾節點
        /// </summary>
        private Node<T> LastNode;

        /// <summary>
        /// 判斷當前鏈表是否為空鏈表
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty()
        {
            return HeadNode == null;
        }

        /// <summary>
        /// 插入節點
        /// </summary>
        public void AddNode(T item)
        {
            // 新建一個節點
            Node<T> newNode = new Node<T>(item);
           
            // 判斷頭節點是否為null,如果為null,那么新建的節點就是頭節點,同時也是尾節點
            if (IsEmpty())
            {
                // 如果是空鏈表,則將頭節點和尾節點都指向新建的節點
                HeadNode = newNode;
                LastNode = newNode;
            }
            else
            {
                // 尾節點的指針指向新建的節點
                // 新建的節點變為尾節點
                LastNode.Next = newNode;
                LastNode = newNode;
            }
            // 將新建的節點添加到集合中
            ListNode.Add(newNode);
        }
    }
}

在Main方法里面調用:

using System;
using System.Collections.Generic;

namespace SingleLinkedListDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            int num;
            string name;
            int score;

            Console.WriteLine("請輸入5位學生的成績:");
            SingleLinkedList<Student> linkedList = new SingleLinkedList<Student>();
            for (int i = 0; i < 5; i++)
            {
                Console.Write("請輸入學號:");
                num = int.Parse(Console.ReadLine());
                Console.Write("請輸入姓名:");
                name = Console.ReadLine();
                Console.Write("請輸入成績:");
                score = int.Parse(Console.ReadLine());
                Student student = new Student(number: num, name: name, score: score);
                linkedList.AddNode(student);
                Console.WriteLine("----------------");
            }

            Console.WriteLine();
            Console.WriteLine("輸出學生成績信息");
            List<Node<Student>> list = linkedList.ListNode;
            foreach (var item in list)
            {
                Console.WriteLine($"學號: {item.Data.Number},姓名: {item.Data.Name},成績: {item.Data.Score}");
                Console.WriteLine();
            }

            Console.ReadKey();
        }
    }
}

程序運行結果:

2、單向鏈表節點的刪除

在單向鏈表類型的數據結構中,若要在鏈表中刪除一個節點,則根據所刪除節點的位置會有以下三種不同的情況。

1、刪除鏈表的第一個節點

如果是刪除鏈表中的第一個節點,只要把鏈表的頭指針指向第二個節點即可,如圖所示:

程序參考代碼:

if(first.data == delNode.data)
    first=first.next;

2、刪除鏈表內的中間節點

如果是刪除鏈表內的中間節點,那么只要將刪除節點的前一個節點的指針,指向要刪除節點的下一個節點即可,如圖所示:

 程序參考代碼:

3、刪除鏈表的最后一個節點

如果是刪除鏈表的最后一個節點,那么只要將指向最后一個節點的指針,直接指向null即可,如圖所示:

程序參考代碼

我們還是以上面的例子進行講解在鏈表中刪除節點。輸入學號,如果學號存在,則在鏈表中刪除,然后打印出當前鏈表中的節點。如果學號不存在,則給出提示信息。要結束輸入時,請輸入“-1”,此時打印出鏈表中的節點信息。

這時上面創建的泛型類就不符合需求了,我們重新創建一個節點類:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SingleLinkedListDemo
{
    /// <summary>
    /// 演示刪除節點使用的節點類
    /// </summary>
    public class StudentNode
    {
        /// <summary>
        /// 學號
        /// </summary>
        public int Number { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 成績
        /// </summary>
        public int Score { get; set; }

        /// <summary>
        /// 指針 指向下一個元素
        /// </summary>
        public StudentNode Next { get; set; }

        public StudentNode(int number,string name,int score)
        {
            Number = number;
            Name = name;
            Score = score;
        }
    }
}

鏈表類:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SingleLinkedListDemo
{
    public class StudentLinkedList
    {

        public List<StudentNode> ListNode { get; set; }


        public StudentLinkedList()
        {
            ListNode = new List<StudentNode>();
        }


        /// <summary>
        /// 頭節點
        /// </summary>
        public StudentNode HeadNode;

        /// <summary>
        /// 尾節點
        /// </summary>
        public StudentNode LastNode;

        /// <summary>
        /// 判斷當前鏈表是否為空鏈表
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty()
        {
            return HeadNode == null;
        }

        /// <summary>
        /// 添加節點
        /// </summary>
        /// <param name="node"></param>
        public void AddNode(StudentNode node)
        {
            StudentNode newNode = node;
            // 判斷頭節點是否為null,如果為null,那么新建的節點就是頭節點,同時也是尾節點
            if (IsEmpty())
            {
                // 如果是空鏈表,則將頭節點和尾節點都指向新建的節點
                HeadNode = newNode;
                LastNode = newNode;
            }
            else
            {
                // 尾節點的指針指向新建的節點
                // 新建的節點變為尾節點
                LastNode.Next = newNode;
                LastNode = newNode;
            }
            // 將新建的節點添加到集合中
            ListNode.Add(newNode);
        }

        /// <summary>
        /// 打印
        /// </summary>
        public void Print()
        {
            StudentNode current = HeadNode;
            while (current != null)
            {
                Console.WriteLine("[" + current.Number + " " + current.Name + " " + current.Score + "]");
                current = current.Next;
            }
            Console.WriteLine();
        }

        /// <summary>
        /// 刪除節點
        /// </summary>
        /// <param name="delNode"></param>
        public void DeleteNode(StudentNode delNode)
        {
            StudentNode newNode;
            StudentNode tmpNode;

            // 如果刪除的是第一個節點
            if(HeadNode.Number==delNode.Number)
            {
                // 頭指針指向第二個節點
                HeadNode = HeadNode.Next;
            }
            else if(LastNode.Number==delNode.Number)
            {
                // 刪除的是最后一個節點
                newNode = HeadNode;
                // 循環找到最后一個節點的前一個節點
                // 當退出循環的時候newNode就是最后一個節點的前一個節點
                while(newNode.Next!=LastNode)
                {
                    // 指針后移,指向下一個節點
                    newNode = newNode.Next;
                }
                // 最后一個節點的前一個節點的next賦值為null
                newNode.Next = null;
                LastNode = newNode;
            }
            else
            {
                // 刪除的是中間的節點
                newNode = HeadNode;
                tmpNode = HeadNode;
                // 循環找到要刪除的節點
                // 循環退出時tmpNode節點就是要刪除節點的前一個節點,newNode節點就是要刪除的節點
                while(newNode.Number!=delNode.Number)
                {
                    tmpNode = newNode;
                    // 后移,指向下一個節點
                    newNode = newNode.Next;
                }
                // 要刪除節點的前一個節點的next指向刪除節點的下一個節點
                tmpNode.Next = newNode.Next;
            }
        }

    }
}

Main方法里面調用:

using System;
using System.Collections.Generic;

namespace SingleLinkedListDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 創建一個單向鏈表
            //int num;
            //string name;
            //int score;

            //Console.WriteLine("請輸入5位學生的成績:");
            //SingleLinkedList<Student> linkedList = new SingleLinkedList<Student>();
            //for (int i = 0; i < 5; i++)
            //{
            //    Console.Write("請輸入學號:");
            //    num = int.Parse(Console.ReadLine());
            //    Console.Write("請輸入姓名:");
            //    name = Console.ReadLine();
            //    Console.Write("請輸入成績:");
            //    score = int.Parse(Console.ReadLine());
            //    Student student = new Student(number: num, name: name, score: score);
            //    linkedList.AddNode(student);
            //    Console.WriteLine("----------------");
            //}

            //Console.WriteLine();
            //Console.WriteLine("輸出學生成績信息");
            //List<Node<Student>> list = linkedList.ListNode;
            //foreach (var item in list)
            //{
            //    Console.WriteLine($"學號: {item.Data.Number},姓名: {item.Data.Name},成績: {item.Data.Score}");
            //    Console.WriteLine();
            //} 
            #endregion

            #region 刪除單向鏈表中的節點
            Random rand = new Random();
            StudentLinkedList list = new StudentLinkedList();
            int i, j, findword = 0;
            int[,] data = new int[12, 10];
            String[] name = new String[] { "Allen", "Scott",
                "Marry", "Jon", "Mark", "Ricky", "Lisa",
                "Jasica", "Hanson", "Amy", "Bob", "Jack" };
            Console.WriteLine("學號 成績  學號 成績  學號 成績  學號  成績\n ");
            // 鏈表里面添加12個節點
            for (i = 0; i < 12; i++)
            {
                data[i, 0] = i + 1;
                data[i, 1] = (Math.Abs(rand.Next(50))) + 50;
                StudentNode node = new StudentNode(data[i, 0], name[i], data[i, 1]);
                list.AddNode(node);
            }
            // 分三行輸出
            for (i = 0; i < 3; i++)
            {
                for (j = 0; j < 4; j++)
                    Console.Write("[" + data[j * 3 + i, 0] + "]  [" + data[j * 3 + i, 1] + "]  ");
                Console.WriteLine();
            }
            while (true)
            {
                Console.Write("請輸入要刪除成績的學生學號,結束輸入-1: ");
                findword = int.Parse(Console.ReadLine());
                if (findword == -1)
                    break;
                else
                {
                    StudentNode current = new StudentNode(list.HeadNode.Number, list.HeadNode.Name, list.HeadNode.Score);
                    current.Next = list.HeadNode.Next;
                    while (current.Number != findword) current = current.Next;
                    list.DeleteNode(current);
                }
                Console.WriteLine("刪除后成績的鏈表,請注意!要刪除的成績其學生的學號必須在此鏈表中\n");
                list.Print();
            }
            #endregion

            Console.ReadKey();
        }
    }
}

程序運行結果:

3、單向鏈表插入新節點

在單向鏈表中插入新節點,如同一列火車中加入新的車廂,有三種情況:加到第一個節點之前、加到最后一個節點之后以及加到此鏈表中間任一位置。

1、新節點插入第一個節點之前

將新節點插入到第一個節點之前,新節點即成為此鏈表的首節點,只需要把新節點的指針指向鏈表原來的第一個節點,再把鏈表頭指針指向新節點即可,如圖所示:

2、新節點插入最后一個節點之后

將新節點插入到最后一個節點之后,只需要把鏈表的最后一個節點的指針指向新節點,新節點的指針在指向null即可,如圖所示:

3、新節點插入鏈表中間位置

例如插入的節點是在X和Y之間,只需要將X節點的指針指向新節點,如圖所示:

然后將新節點的指針指向Y節點即可,如圖所示:

下面我們以泛型Node類為例,講解如何插入節點

using System;
using System.Collections.Generic;

namespace SingleLinkedListDemo
{
    /// <summary>
    /// 單向鏈表類
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SingleLinkedList<T>
    {
        /// <summary>
        /// 存放所有鏈表節點的集合
        /// </summary>
        public List<Node<T>> ListNode { get; set; }

        /// <summary>
        /// 構造函數
        /// </summary>
        public SingleLinkedList()
        {
            ListNode = new List<Node<T>>();
        }

        /// <summary>
        /// 頭節點
        /// </summary>
        private Node<T> HeadNode;

        /// <summary>
        /// 尾節點
        /// </summary>
        private Node<T> LastNode;

        /// <summary>
        /// 判斷當前鏈表是否為空鏈表
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty()
        {
            return HeadNode == null;
        }

        /// <summary>
        /// 新增節點
        /// </summary>
        public void AddNode(T item)
        {
            // 新建一個節點
            Node<T> newNode = new Node<T>(item);
           
            // 判斷頭節點是否為null,如果為null,那么新建的節點就是頭節點,同時也是尾節點
            if (IsEmpty())
            {
                // 如果是空鏈表,則將頭節點和尾節點都指向新建的節點
                HeadNode = newNode;
                LastNode = newNode;
            }
            else
            {
                // 尾節點的指針指向新建的節點
                // 新建的節點變為尾節點
                LastNode.Next = newNode;
                LastNode = newNode;
            }
            // 將新建的節點添加到集合中
            ListNode.Add(newNode);
        }

        /// <summary>
        /// 插入節點
        /// </summary>
        /// <param name="item">要插入的節點的值</param>
        /// <param name="index">要插入節點的位置</param>
        public void InsertNode(T item,int index)
        {
            // 創建新的節點
            Node<T> newNode = new Node<T>(item);
            //Node<T> tmpNode = new Node<T>(item);

            // 判斷當前鏈表是否為空鏈表
            if(IsEmpty())
            {
                HeadNode = newNode;
                LastNode = newNode;
            }
            else
            {
                // 插入第一個節點
                if(index==0)
                {
                    // 新節點執行現在的頭節點
                    newNode.Next = HeadNode;
                    // 新節點變為新的頭節點
                    HeadNode = newNode;
                }
                else if(index==GetLinkedListLength()-1)
                {
                    // 插入尾節點
                    // 定義一個臨時節點tempNode指向HeadNode
                    Node<T> tempNode = HeadNode;
                    // 循環找到尾節點
                    while(true)
                    {
                        // 如果tempNode的next不為null,說明當前節點不是尾節點,則后移
                        if(tempNode.Next!=null)
                        {
                            // 當前tempNode后移
                            tempNode = tempNode.Next;
                        }
                        else
                        {
                            // tempNode的next為null,說明tempNode節點是尾節點,則退出循環
                            break;
                        }
                    }
                    // tempNode是尾節點,則將尾節點的next指向新的節點
                    tempNode.Next = newNode;
                }
                else
                {
                    #region 插入中間位置
                    // 定義臨時節點指向頭節點
                    Node<T> tempNode = HeadNode;
                    // 經過index-1次循環后移,tempNode移動到要插入位置的前一個節點
                    for (int i = 0; i <=index-1; i++)
                    {
                        // tempNode節點每次后移一個位置
                        tempNode = tempNode.Next;
                    }
                    // 要插入位置的前一個節點
                    Node<T> preNode = tempNode;
                    // 要插入位置的節點
                    Node<T> currentNode = preNode.Next;
                    // 修改next指向,前一個節點指向新節點
                    preNode.Next = newNode;
                    // 新節點指向當前位置的節點
                    newNode.Next = currentNode;
                    #endregion
                }
            }
        }

        /// <summary>
        /// 獲取鏈表長度
        /// </summary>
        /// <returns></returns>
        public int GetLinkedListLength()
        {
            // 長度
            int length = 0;
            if(HeadNode==null)
            {
                length = 0;
            }
            else
            {
                Node<T> tempNode = HeadNode;
                // 循環
                while(true)
                {
                    if(tempNode.Next!=null)
                    {
                        // 當前臨時節點后移到下一個節點
                        tempNode = tempNode.Next;
                        // 長度自增
                        length++;
                    }
                    else
                    {
                        // 說明循環到了尾節點,退出循環
                        length++;
                        break;
                    }
                }
            }
            return length;
        }

        /// <summary>
        /// 打印
        /// </summary>
        public void Print()
        {
            //StudentNode current = HeadNode;
            //while (current != null)
            //{
            //    Console.WriteLine("[" + current.Number + " " + current.Name + " " + current.Score + "]");
            //    current = current.Next;
            //}

            Node<T> current = HeadNode;
            while (current != null)
            {
                Console.Write( current.Data+"  ");
                current = current.Next;
            }
            Console.WriteLine();
        }
    }
}

Main方法中調用:

using System;
using System.Collections.Generic;

namespace SingleLinkedListDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 創建一個單向鏈表
            //int num;
            //string name;
            //int score;

            //Console.WriteLine("請輸入5位學生的成績:");
            //SingleLinkedList<Student> linkedList = new SingleLinkedList<Student>();
            //for (int i = 0; i < 5; i++)
            //{
            //    Console.Write("請輸入學號:");
            //    num = int.Parse(Console.ReadLine());
            //    Console.Write("請輸入姓名:");
            //    name = Console.ReadLine();
            //    Console.Write("請輸入成績:");
            //    score = int.Parse(Console.ReadLine());
            //    Student student = new Student(number: num, name: name, score: score);
            //    linkedList.AddNode(student);
            //    Console.WriteLine("----------------");
            //}

            //Console.WriteLine();
            //Console.WriteLine("輸出學生成績信息");
            //List<Node<Student>> list = linkedList.ListNode;
            //foreach (var item in list)
            //{
            //    Console.WriteLine($"學號: {item.Data.Number},姓名: {item.Data.Name},成績: {item.Data.Score}");
            //    Console.WriteLine();
            //} 
            #endregion

            #region 刪除單向鏈表中的節點
            //Random rand = new Random();
            //StudentLinkedList list = new StudentLinkedList();
            //int i, j, findword = 0;
            //int[,] data = new int[12, 10];
            //String[] name = new String[] { "Allen", "Scott",
            //    "Marry", "Jon", "Mark", "Ricky", "Lisa",
            //    "Jasica", "Hanson", "Amy", "Bob", "Jack" };
            //Console.WriteLine("學號 成績  學號 成績  學號 成績  學號  成績");
            //// 鏈表里面添加12個節點
            //for (i = 0; i < 12; i++)
            //{
            //    data[i, 0] = i + 1;
            //    data[i, 1] = (Math.Abs(rand.Next(50))) + 50;
            //    StudentNode node = new StudentNode(data[i, 0], name[i], data[i, 1]);
            //    list.AddNode(node);
            //}
            //// 分三行輸出
            //for (i = 0; i < 3; i++)
            //{
            //    for (j = 0; j < 4; j++)
            //        Console.Write("[" + data[j * 3 + i, 0] + "]  [" + data[j * 3 + i, 1] + "]  ");
            //    Console.WriteLine();
            //}
            //while (true)
            //{
            //    Console.Write("請輸入要刪除成績的學生學號,結束輸入-1: ");
            //    findword = int.Parse(Console.ReadLine());
            //    if (findword == -1)
            //        break;
            //    else
            //    {
            //        StudentNode current = new StudentNode(list.HeadNode.Number, list.HeadNode.Name, list.HeadNode.Score);
            //        current.Next = list.HeadNode.Next;
            //        while (current.Number != findword) current = current.Next;
            //        list.DeleteNode(current);
            //    }
            //    Console.WriteLine("刪除后成績的鏈表,請注意!要刪除的成績其學生的學號必須在此鏈表中\n");
            //    list.Print();
            //}
            #endregion

            #region 單向鏈表中插入節點
            SingleLinkedList<int> linkedList = new SingleLinkedList<int>();
            linkedList.AddNode(1);
            linkedList.AddNode(45);
            linkedList.AddNode(56);
            linkedList.AddNode(389);
            List<Node<int>> list = linkedList.ListNode;
            Console.WriteLine("插入前鏈表元素");
            linkedList.Print();
            Console.WriteLine();
            // 插入頭節點之前
            linkedList.InsertNode(57, 0);
            Console.WriteLine("插入頭節點后鏈表元素");
            linkedList.Print();
            Console.WriteLine();
            // 插入尾節點之后
            linkedList.InsertNode(123, linkedList.GetLinkedListLength()-1);
            Console.WriteLine("插入尾節點后鏈表元素");
            linkedList.Print();
            Console.WriteLine();
            // 插入中間節點
            int index= new Random().Next(0, linkedList.GetLinkedListLength() - 1);
            linkedList.InsertNode(935, index);
            Console.WriteLine("插入中間節點后鏈表元素");
            linkedList.Print();
            Console.WriteLine();
            #endregion
            Console.ReadKey();
        }
    }
}

程序運行結果:

GitHub地址:git@github.com:JiangXiaoLiang1988/SingleLinkedList.git


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM