【c# .net】双向链表( LinkedList )

原文链接: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 (Node); 移除指定值的第一个匹配项
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);

  运行结果:

 

 

 

  

 

posted @ 2024-03-13 00:52  yinghualeihenmei  阅读(271)  评论(0编辑  收藏  举报