5,泛型单链表

Posted xiaojvhuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5,泛型单链表相关的知识,希望对你有一定的参考价值。

聊表反转实现思路:

1)不要试图在原来链表试图修剪,比较容易掉坑,避免链表断裂

2)新建一个表头rverseHeader,只要用来反转前后节点地址指向,也是新链表头

3)新建临时节点,curNode移到当前节点,nexNode移到下一节点防止链表断裂

4)从旧链表往下查找,断开当然节点,并设置curNode.Next = rverseHeader.Next,新头指定当前节点rverseHeader.Next = curNode

5)旧头节点Header.Next 重新指向rverseHeader.Next

C#代码实现:

  1 using System;
  2 
  3 namespace 数据结构
  4 {
  5     public class Linked<T>
  6     {
  7         //头部节点
  8         private Node Header { get; } = new Node(0, default);
  9 
 10         //添加到链表末尾
 11         public void Append(Node node)
 12         {
 13             //临时节点,从指向头部节点开始查找
 14             Node temp = this.Header;
 15             //下节点为空才链表结尾
 16             while (temp.Next != null)
 17             {
 18                 //指向下一个节点
 19                 temp = temp.Next;
 20             }
 21             //加到末尾
 22             temp.Next = node;
 23         }
 24 
 25         //插入节点
 26         public void Insert(Node node)
 27         {
 28             //临时节点,从指向头部节点开始查找
 29             Node temp = this.Header;
 30             //下节点不为空继续向下查找
 31             while (temp.Next != null)
 32             {
 33                 if (node.Index < temp.Next.Index)
 34                 {
 35                     //如果小于下一个节点就插到下一个节点前面
 36                     node.Next = temp.Next;
 37                     temp.Next = node;
 38                     return;
 39                 }
 40                 else if (node.Index == temp.Next.Index)
 41                 {
 42                     //如果等于下一个节点,节点以存在返回
 43                     Console.WriteLine($"节点{node.Index}已经存在");
 44                     return;
 45                 }
 46                 //继续查找
 47                 temp = temp.Next;
 48             }
 49             //插入末尾
 50             temp.Next = node;
 51         }
 52 
 53         //移除节点
 54         public void Remove(int index)
 55         {
 56             //临时节点,从指向头部节点开始查找
 57             Node temp = this.Header;
 58             //下一节点不为空继续往下找
 59             while (temp.Next != null)
 60             {
 61                 if (temp.Next.Index == index)
 62                 {
 63                     //找到,Next 指向下下个节点
 64                     temp.Next = temp.Next.Next;
 65                     return;
 66                 }
 67                 else
 68                 {
 69                     //继续查找
 70                     temp = temp.Next;
 71                 }
 72             }
 73             Console.WriteLine($"没找节点{index}");
 74         }
 75 
 76         //反转列表
 77         public void Rverse()
 78         {
 79             //指向当前节点
 80             Node curNode = this.Header.Next;
 81             //当断开当前节点时,指向下一节点,避免链表断开
 82             Node nexNode = null;
 83             //新表头
 84             Node rverseHeader = new Node(0, default);
 85             //只有一个元素不用处理
 86             if (Header.Next == null || Header.Next.Next == null)
 87             {
 88                 return;
 89             }
 90             while (curNode != null)
 91             {
 92                 //指向下一节点
 93                 nexNode = curNode.Next;
 94                 //断开当前节点,并指向上一节点地址,当第一次进入上节点地址为空
 95                 curNode.Next = rverseHeader.Next;
 96                 //头节点指向当前节点
 97                 rverseHeader.Next = curNode;
 98                 //指向下节点
 99                 curNode = nexNode;
100             }
101             //旧节点头重新指向反转后第一个元素
102             Header.Next = rverseHeader.Next;
103         }
104 
105         //打印所有节点
106         public void Scan()
107         {
108             //建立临时节点,从指向头部节点开始查找
109             Node temp = this.Header;
110             while (temp.Next != null)
111             {
112                 Console.WriteLine(temp.Next.ToString());
113                 //临时节点指向下一节点
114                 temp = temp.Next;
115             }
116         }
117 
118         //链表节点
119         public class Node
120         {
121             public int Index { get; set; }
122             public T Value { get; set; }
123             public Node Next { get; set; }
124             public Node(int index, T val)
125             {
126                 this.Index = index;
127                 this.Value = val;
128             }
129             //重写Tostring方法方便查看
130             public override string ToString()
131             {
132                 return $"index={Index},value={Value}";
133             }
134         }
135     }
136 
137     public class LinkedListDemo
138     {
139         static void Main(string[] agrs)
140         {
141             Console.WriteLine("向链表添加三位骨架精奇同志");
142             var Linked = new Linked<string>();
143             Linked.Append(new Linked<string>.Node(2, "张三"));
144             Linked.Append(new Linked<string>.Node(5, "李四"));
145             Linked.Append(new Linked<string>.Node(4, "王五"));
146             Linked.Scan();
147             //---------------------------------------------------
148             Console.WriteLine("删除王五");
149             Linked.Remove(4);
150             Linked.Scan();
151             //---------------------------------------------------
152             Console.WriteLine("插入小明");
153             Linked.Insert(new Linked<string>.Node(4, "小明"));
154             Linked.Scan();
155             Console.WriteLine("插入小李");
156             Linked.Insert(new Linked<string>.Node(1, "小李"));
157             Linked.Scan();
158             //---------------------------------------------------
159             Console.WriteLine("反转链表");
160             Linked.Rverse();
161             Linked.Scan();
162         }
163     }
164 }

技术图片

以上是关于5,泛型单链表的主要内容,如果未能解决你的问题,请参考以下文章

Java 大话数据结构 线性表之单链表

日常学习随笔-单链表学习测试

合并两个有序单链表

5种常见的链表基本操作

每天学习亿点点系列——重温单链表

数据结构 链表