一、涉及到的知識點
1.ListNode<T>類
????????ListNode<T>是一個泛型類,用于表示鏈表中的一個節點。Value和Next屬性是ListNode<T>最基本的屬性,用于表示節點的值和指向下一個節點的引用。但是,完全可以根據實際需求添加其他屬性,例如一個指向前一個節點的引用的Previous的屬性,它是一個可空的ListNode<T>類型,表示前一個節點的引用。這個屬性可以用于實現雙向鏈表,其中每個節點都有一個指向前一個節點和下一個節點的引用。
????????總之,ListNode<T>類的屬性數量和類型取決于工程需求。在實際開發中,可以根據實際需求自定義ListNode<T>類。
????????ListNode<T>中,Value屬性存儲節點的值,而Next屬性是指向鏈表中下一個節點的引用。Next屬性的類型為ListNode<T>,這意味著它指向相同類型的節點。這種設計使得使用相同類型的節點來構建一個鏈表,而不需要為每個節點創建一個特定的類型。
public class ListNode<T>(T value)
{public T Value { get; set; } = value;public ListNode<T>? Next { get; set; } = null;public ListNode<T>? Previous { get; set; } = null;
}
2.LinkedList<T>類
????????LinkedList<T>類是一個泛型類,用于實現鏈表數據結構。鏈表是一種線性數據結構,其中每個元素(節點)包含一個值和指向下一個元素(節點)的引用。LinkedList<T>類在C#中通常用于存儲相同類型的元素集合。LinkedList<T>類的主要特點包括:
- 泛型類型參數T:允許存儲任何類型的數據,只要它們實現了System.IEquatable<T>接口。
- 節點類:LinkedList<T>使用內部類ListNode<T>表示鏈表中的節點。ListNode<T>包含一個值(Value屬性)和對下一個節點的引用(Next屬性)。
- 頭部和尾部節點:LinkedList<T>維護兩個節點引用:_head表示鏈表的頭部節點,_tail表示鏈表的尾部節點。當向鏈表中添加或刪除節點時,這些引用會相應地更新。
- 插入和刪除節點:LinkedList<T>提供了一些方法來插入和刪除節點,如AddFirst、AddLast、Insert、Remove等。這些方法會更新頭部和尾部節點的引用,以保持鏈表的正確性。
- 遍歷鏈表:LinkedList<T>提供了一些方法來遍歷鏈表中的節點,如GetEnumerator。這使得我們可以使用foreach循環來訪問鏈表中的所有節點。
????????C#標準庫中已經提供了System.Collections.Generic.LinkedList<T>類。在實際開發中,可以直接使用這個類,而無需自己實現。在使用LinkedList<T>時,只需要設計實現自己的工程需要的方法,這些方法是自定義的。
public class LinkedList<T>
{private static ListNode<T>? _head;private static ListNode<T>? _current;public static ListNode<T>? Current { get => _current; set => _current = value; }public static ListNode<T>? Head { get => _head; set => _head = value; }public LinkedList() => _head = null;/// <summary>/// 泛型類在鏈表尾部插入新數據/// 追加新數據/// </summary>public void Append(T value){var newNode = new ListNode<T>(value);if (_head == null){_head = newNode;}else{var current = _head;while (current.Next != null){current = current.Next;}current.Next = newNode;_current = newNode;}}/// <summary>/// 在當前位置插入數據,/// 不對數據排序,也不比較數據/// </summary>public static void Insert(T value){// 創建一個新的節點var newNode = new ListNode<T>(value);// 如果鏈表為空,將新節點設置為頭節點if (_head == null){_head = newNode;_current = newNode;return;}// 找到當前節點var current = _current;if (current == null){_current = _head;while (_current.Next != null){_current = _current.Next;}current = _current;}// 在當前位置插入新節點newNode.Next = current.Next;newNode.Previous = current;current.Next = newNode;_current = newNode;}/// <summary>/// 輸出鏈表數據/// </summary>public static void PrintList(){var current = _head;while (current != null){Console.Write(current.Value + " ");current = current.Next;}Console.WriteLine();}/// <summary>/// 當前節點指針移動到鏈表頭/// 當前節點=頭節點/// </summary>public static void MoveFirst(){if (_head != null){_current = _head;}}/// <summary>/// 當前節點指針移動到下一個節點/// 當前節點=下一個節點/// </summary>public static void MoveNext(){if (_current != null && _current.Next != null){_current = _current.Next;}}
}
????????在LinkedList<T>類中,_head屬性是一個ListNode<T>類型的變量,用于存儲鏈表的頭部節點。當向鏈表中插入新節點時,我們會創建一個新的ListNode<T>實例,并將其設置為_head或將其附加到現有鏈表的末尾。鏈表的遍歷過程也會使用ListNode<T>類,逐個訪問鏈表中的節點。
二、Main方法的實例
class Program{public static void Main(string[] args){ArgumentNullException.ThrowIfNull(args);var list = new LinkedList<int>();list.Append(5);list.Append(2);list.Append(8);list.Append(1);LinkedList<int>.PrintList(); // 輸出:1 8 2 5list.Append(11);LinkedList<int>.PrintList(); // 輸出:1 8 2 5 11LinkedList<int>.MoveFirst();LinkedList<int>.Insert(12);LinkedList<int>.PrintList();LinkedList<int>.MoveNext();LinkedList<int>.Insert(13);LinkedList<int>.PrintList();}}
//運行結果:
/*
5 2 8 1
5 2 8 1 11
5 12 2 8 1 11
5 12 2 13 8 1 11*/