【c# .net】雙向連結串列( LinkedList )

yinghualeihenmei發表於2024-03-13

原文連結:https://zhuanlan.zhihu.com/p/307436697?utm_id=0

  

1)下表列出了 LinkedListNode<T> 類的一些常用的 屬性:

屬性描述
LinkedList<T>? List { get; } 獲取 LinkedList 所屬的 LinkedListNode
LinkedListNode<T>? Next { get; } 獲取下一個節點
LinkedListNode<T>? Previous { get; } 獲取上一個節點
T Value { get; set; } 獲取節點中包含的值

LinkedList<T> 類的方法和屬性
1)下表列出了 LinkedList<T> 類的一些常用的 屬性:

屬性 描述
int Count { get; } 獲取實際節點數
LinkedListNode<T>? First { get; } 獲取第一個節點
LinkedListNode<T>? Last { get; } 獲取最後一個節點
2)下表列出了 LinkedList<T> 類的一些常用的 方法:

方法 描述
void AddAfter(LinkedListNode, T value); 在指定現有節點後新增包含指定值的新節點
void AddBefore(LinkedListNode, T value); 在指定現有節點前新增包含指定值的新節點
void AddFirst(T value); 在開頭處新增包含指定值的新節點
void AddLast(T value); 在結尾處新增包含指定值的新節點
bool Contains(T value); 確定某值是否在
LinkedListNode Find (T value); 查詢包含指定值的第一個節點
LinkedListNode FindLast (T value); 查詢包含指定值的最後一個節點
void Remove (T value); 移除指定值的第一個匹配項
void RemoveFirst (); 移除開頭處的節點
void RemoveLast (); 移除結尾處的節點
void Clear(); 移除所有節點
void CopyTo (T[] array, int index); 將整個 LinkedList 複製到指定一維陣列的指定索引處

程式碼演示

注意:為了方便閱讀,以下將程式碼拆分為多段進行演示,實際執行可以把程式碼直接拼接起來

using System;
using System.Collections;
using System.Collections.Generic;

namespace LinkedListTest
{
    class Program
    {
        static void Main(string[] args)
        {
            LinkedListTest();
            Console.ReadKey();
        }

        //先封裝兩個方法,方便後面程式碼驗證使用

        /// <summary>
        /// 分隔線
        /// </summary>
        static void 分隔線()
        {
            Console.WriteLine("\n ------------------------------------------- \n");
        }
        /// <summary>
        /// 遍歷 LinkedList 中的所有元素
        /// </summary>
        static void FLinkedList<T>(LinkedList<T> linkedList)
        {
            Console.WriteLine("元素:");
            foreach (var item in linkedList)
            {
                Console.Write(" " + item);
            }
            分隔線();
        }
        static void LinkedListTest()
        {
            //多維陣列,交錯陣列,字典,排序列表,雜湊表,動態陣列都無法對連結串列進行賦值
            //一維陣列,列表,雜湊集,棧,佇列都可以對連結串列進行賦值
            int[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ,10};
            List<int> list = new List<int>(array);
            HashSet<int> hashset = new HashSet<int>(array);
            Stack<int> stack = new Stack<int>(array);
            Queue<int> queue = new Queue<int>(array);
            //new 時必須為泛型,無法指定容量
            LinkedList<int> linkedList = new LinkedList<int>(array);
            LinkedList<int> linkedList_list = new LinkedList<int>(list);
            LinkedList<int> linkedList_hashset = new LinkedList<int>(hashset);
            LinkedList<int> linkedList_stack = new LinkedList<int>(stack);
            LinkedList<int> linkedList_queue = new LinkedList<int>(queue);

            Console.WriteLine("\n linkedList 長度:{0}", linkedList.Count);
            LinkedListNode<int> node_f = linkedList.First;

            Console.WriteLine("\n linkedList 第一節點的值:{0}", node_f.Value);
            Console.WriteLine("\n 下一個節點的值:{0}", node_f.Next.Value);
            //如果當前節點位於連結串列的頂點,則無法獲取頂點以外節點的值,因為頂點外無引用值,會報錯
            //但是獲取節點是可以的,頂點以上存在節點,因為有指標指向其他的空節點
            //只要記憶體足夠,理論上可以說沒有頂點,頂點只是相對的
            //Console.WriteLine("\n 上一個節點的值:{0}", node_f.Previous.Value); //此處會報錯
            //透過 AddBefore 方法可以新增上一個節點
            linkedList.AddBefore(node_f,10086); 
            Console.WriteLine("\n 上一個節點的值:{0}", node_f.Previous.Value);
            Console.WriteLine("\n linkedList 長度:{0}", linkedList.Count);

            LinkedListNode<int> node_l = linkedList.Last;
            Console.WriteLine("\n linkedList 最後節點的值:{0}", linkedList.Last.Value);
            //遍歷連結串列只需要使用 foreach 即可
            FLinkedList(linkedList);
        }
    }
}

  執行結果:

 Console.WriteLine("\n 1.在指定現有節點後新增包含指定值的新節點:");
            //新增的值不能為null,且資料型別必須一致
            linkedList.AddAfter(node_f, 9);
            FLinkedList(linkedList);

            Console.WriteLine("\n 2.在指定現有節點前新增包含指定值的新節點:");
            linkedList.AddBefore(node_l, 1);
            FLinkedList(linkedList);

            Console.WriteLine("\n 3.在開頭處新增包含指定值的新節點:");
            linkedList.AddFirst(100);
            FLinkedList(linkedList);

            Console.WriteLine("\n 4.在結尾處新增包含指定值的新節點:");
            linkedList.AddLast(100);
            FLinkedList(linkedList);

執行結果:

     Console.WriteLine("\n 5.移除指定值的第一個匹配項:");
            linkedList.Remove(100);
            FLinkedList(linkedList);

            Console.WriteLine("\n 6.移除開頭處的節點:");
            linkedList.RemoveFirst();
            FLinkedList(linkedList);

            Console.WriteLine("\n 7.移除結尾處的節點:");
            linkedList.RemoveLast();
            FLinkedList(linkedList);

  執行結果:

  Console.WriteLine("\n 8.確定某值是否在:");
            Console.WriteLine("\n 20是否存在:{0}", linkedList.Contains(20));
            Console.WriteLine("\n 10是否存在:{0}", linkedList.Contains(10));

            Console.WriteLine("\n 9.查詢包含指定值的第一個節點:");
            //如果查詢的值不存在,則忽略本次操作,並不會報錯
            LinkedListNode<int> head = linkedList.Find(9);
            Console.Write("\n 頭9的上個節點:{0}", head.Previous.Value);
            Console.Write("\n 頭9的下個節點:{0}", head.Next.Value);
            分隔線();

            Console.WriteLine("\n 10.查詢包含指定值的最後一個節點:");
            LinkedListNode<int> end = linkedList.FindLast(9);
            Console.Write("\n 尾9的上個節點:{0}", end.Previous.Value);
            Console.Write("\n 尾9的下個節點:{0}", end.Next.Value);
            分隔線();

            Console.WriteLine("\n 11.將整個 LinkedList 複製到指定一維陣列的指定索引處:");
            //複製時,需要注意容器陣列長度,長度不足會越界報錯,且資料型別必須一致
            int[] array2 = new int[linkedList.Count];
            linkedList.CopyTo(array2, 0);
            foreach (var item in array2) Console.Write(" "+item);

  執行結果:

  

相關文章