目錄
一、涉及到的知識點
1.插入算法
2.示例中current?和?_current?的作用
3.current?和?_current 能否合并為一個變量
4.單向鏈表節點類的三個屬性
(1)Next屬性:
(2)?Value屬性:
(3)Previous屬性:
二、Insert()方法實例
一、涉及到的知識點
1.插入算法
????????在單向鏈表的當前位置插入一個新的節點,在插入新節點之前,需要找到當前節點。如果當前節點為空,需要找到鏈表的最后一個節點,然后將最后一個節點設置為當前節點。這樣,新節點就可以插入到鏈表的末尾。
·????????在插入新節點時,需要正確設置新節點的 Next 和 Previous 屬性。設置新節點的 Next 和 Previous 屬性具體如下:
newNode.Next = current.Next;
newNode.Previous = current;
current.Next = newNode;
_current = newNode;
????????這樣設置確保了新節點被正確地插入到鏈表中,并且鏈表的其他部分也得到正確更新。?
2.示例中current?和?_current?的作用
????????在實例程序中,current?和?_current?的作用是有區別的。它們主要用于在插入新節點時跟蹤鏈表中的當前節點。讓我來解釋一下它們各自的用途:
- current:是一個臨時變量,用于在插入新節點之前找到鏈表中的當前節點。如果鏈表不為空,它會從鏈表頭節點開始遍歷,直到找到最后一個節點。在這個過程中,current?會被不斷更新為當前節點的下一個節點。最后,current?會被設置為最后一個節點。
- _current:是一個靜態變量,用于在整個鏈表操作過程中跟蹤當前節點。在插入新節點時,_current?會被設置為新插入的節點。這樣,在后續的操作中,可以使用?_current?來訪問鏈表中的當前節點。
3.current?和?_current 能否合并為一個變量
????????在源程序中將?current?和?_current?可以合并為一個變量。但是,將它們分開好處更多:
- 代碼的可讀性:使用兩個不同的變量名可以更清楚地表明它們在代碼中的不同作用。使用?_current?作為靜態變量可以清楚地表明它在整個鏈表操作過程中的作用,而使用?current?作為局部變量可以清楚地表明它在插入新節點過程中的作用。
- 代碼的簡潔性:將它們分開可以使代碼更簡潔。如果將它們合并為一個變量,那么在插入新節點之前需要不斷地更新這個變量。而將它們分開,只需要在找到最后一個節點后,將?_current?設置為?current,就可以完成鏈表的插入操作。
????????總之,雖然可以將?current?和?_current?統一為一個變量,但將它們分開可以使代碼更易讀、更簡潔。
4.單向鏈表節點類的三個屬性
????????在C#中,單向鏈表節點(通常稱為節點或列表節點)通常使用一個公共類來表示,該類具有三個主要屬性:
(1)Next屬性:
????????此屬性表示鏈表中當前節點的下一個節點。在單向鏈表中,只能從頭節點開始向前遍歷節點,因此每個節點僅需維護一個指向其后繼節點的引用。Next屬性通常是一個指向ListNode類型對象的引用。在鏈表的末尾,Next屬性將為null。
public class ListNode
{public int Value { get; set; }public ListNode Next { get; set; }public ListNode(int value){Value = value;}
}
?????????或
public class ListNode(int value)
{public int Value { get; set; } = value;public ListNode? Next { get; set; } = null;public ListNode? Previous { get; set; } = null;
}
(2)?Value屬性:
????????此屬性表示當前節點所存儲的值。在鏈表中,每個節點都存儲一個值,該值可以是任何類型,如int、double、string等。Value屬性通常是一個泛型類型T,以便在不同類型的鏈表中重用相同的節點類。
public class ListNode<T>
{public T Value { get; set; }public ListNode<T> Next { get; set; }public ListNode(T value){Value = value;}
}
?????????或
public class ListNode<T>(T value){public T Value { get; set; } = value;public ListNode<T>? Next { get; set; }}
(3)Previous屬性:
????????在某些情況下,需要使用雙向鏈表,即每個節點不僅維護一個指向其后繼節點的引用,還維護一個指向其前驅節點的引用。在這種情況下,Previous屬性表示鏈表中當前節點的前一個節點。Previous屬性通常是一個指向ListNode類型對象的引用。在鏈表的頭部,Previous屬性將為null。
public class ListNode<T>
{ public T Value { get; set; } public ListNode<T> Next { get; set; } public ListNode<T> Previous { get; set; }public ListNode(T value) { Value = value; }
}
二、Insert()方法實例
// 單向鏈表在當前位置插入新數據的方法
namespace _131_10
{public class ListNode(int value){public int Value { get; set; } = value;public ListNode? Next { get; set; } = null;public ListNode? Previous { get; set; } = null;}public class LinkedList{private static ListNode? _head;private static ListNode? _current;public LinkedList() => _head = null;/// <summary>/// 在當前位置插入數據,/// 不對數據排序,也不比較數據/// </summary>public static void Insert(int value){// 創建一個新的節點var newNode = new ListNode(value);// 如果鏈表為空,將新節點設置為頭節點if (_head == null){_head = newNode;_current = newNode;return;}// 找到當前節點var current = _current;if (current == null){//current = _head;_current = _head;while (_current.Next != null){_current = _current.Next;}current = _current;}// 在當前位置插入新節點newNode.Next = current.Next;newNode.Previous = current;current.Next = newNode;_current = newNode;}public static void Display(){var current = _head;while (current != null){Console.Write(current.Value + " ");current = current.Next;}Console.WriteLine();}class Program{static void Main(string[] args){ArgumentNullException.ThrowIfNull(args);// 鏈表數據初始化_head = new(5){Next = new ListNode(2)};_head.Next.Next = new ListNode(8){Next = new ListNode(1)};Display();Console.WriteLine("**初始數據**");_current = _head.Next.Next; //設置當前節點為第三個節點(值為8)Insert(9); //在當前位置插入數據9Display(); Console.WriteLine("**插入9**");}}}
}
//運行結果:
/*
5 2 8 1
**初始數據**
5 2 8 9 1
**插入9***/