6,泛型双向链表
实现思路:
1)同单向链表思路大致相同,只是多来一个pre指向上一节点
2)双向链表删除节点时,不依赖前一节点,可以自我删除,判断如果是删除最后一个元素时直接断开即可
c#代码实现:
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace 数据结构 6 { 7 public class DoubleLinked<T> 8 { 9 //头部节点 10 public Node Header { get;} = new Node(0, default); 11 12 //双链表节点 13 public class Node 14 { 15 public int Index { get; set; } 16 public T Value { get; set; } 17 public Node Next { get; set; } 18 public Node Pre { get; set; } 19 public Node(int index, T value) 20 { 21 this.Index = index; 22 this.Value = value; 23 } 24 //重写Tostring方法方便查看节点 25 public override string ToString() 26 { 27 return $"index={Index},value={Value}"; 28 } 29 } 30 31 //添加到链表末尾 32 public void Append(Node node) 33 { 34 //辅助指针,指向头节点 35 Node pointer = this.Header; 36 //查找链表末尾 37 while (pointer.Next != null) 38 { 39 //指向下一节点 40 pointer = pointer.Next; 41 } 42 //添加到末尾 43 pointer.Next = node; 44 //指向上一节点, 45 node.Pre = pointer; 46 } 47 48 //有序插入 49 public void Insert(Node node) 50 { 51 Node pointer = this.Header; 52 while (pointer.Next != null) 53 { 54 if (node.Index < pointer.Next.Index) 55 { 56 //新指向下一节点 57 node.Next = pointer.Next; 58 //上节点指向新节点 59 pointer.Next = node; 60 //下一节点指向新节点 61 pointer.Next.Pre = node; 62 //新节点指向上一节点 63 node.Pre = pointer; 64 return; 65 } 66 else if (pointer.Next.Index == node.Index) 67 { 68 //如果等于下一个节点,节点以存在返回 69 Console.WriteLine($"节点{node.Index}已经存在"); 70 return; 71 } 72 //没有合适插入位置,指向下一节点 73 pointer = pointer.Next; 74 } 75 //没找到插入位置,添加到末尾 76 pointer.Next = node; 77 node.Pre = pointer; 78 } 79 80 //删节点 81 public void Remove(int index) 82 { 83 if (this.Header.Next == null) 84 { 85 Console.WriteLine($"空链表"); 86 return; 87 } 88 //辅助指针,指向头节点 89 Node pointer = this.Header.Next; 90 //双向链表节点可以自身删除,不用依赖前一节点 91 while (pointer != null) 92 { 93 if (pointer.Index == index) 94 { 95 //前一节点指到下一节点 96 pointer.Pre.Next = pointer.Next; 97 //如果不三节点最后,下一个节点要指向前一节点 98 if (pointer.Next != null) 99 { 100 //下一节点指到前一节点 101 pointer.Next.Pre = pointer.Pre; 102 } 103 return; 104 } 105 else 106 { 107 //没找到继续,指针指向下一节点 108 pointer = pointer.Next; 109 } 110 } 111 Console.WriteLine($"没找节点{index}"); 112 } 113 114 //打印链表 115 public void Scan() 116 { 117 Node pointer = this.Header; 118 while (pointer.Next != null) 119 { 120 Console.WriteLine(pointer.Next.ToString()); 121 pointer = pointer.Next; 122 } 123 } 124 } 125 126 public class DoubleLinkedDemo 127 { 128 static void Main(string[] args) 129 { 130 Console.WriteLine("向链表添加三位骨架精奇同志"); 131 var doubleLinked = new DoubleLinked<string>(); 132 doubleLinked.Append(new DoubleLinked<string>.Node(2, "张三")); 133 doubleLinked.Append(new DoubleLinked<string>.Node(5, "李四")); 134 doubleLinked.Append(new DoubleLinked<string>.Node(4, "王五")); 135 doubleLinked.Scan(); 136 //--------------------------------------------------- 137 Console.WriteLine("删除李四"); 138 doubleLinked.Remove(5); 139 doubleLinked.Scan(); 140 Console.WriteLine("删除张三"); 141 doubleLinked.Remove(2); 142 doubleLinked.Scan(); 143 Console.WriteLine("删除王五"); 144 doubleLinked.Remove(4); 145 doubleLinked.Scan(); 146 //--------------------------------------------------- 147 Console.WriteLine("插入小明"); 148 doubleLinked.Insert(new DoubleLinked<string>.Node(4, "小明")); 149 doubleLinked.Scan(); 150 Console.WriteLine("插入小李"); 151 doubleLinked.Insert(new DoubleLinked<string>.Node(1, "小李")); 152 doubleLinked.Scan(); 153 } 154 } 155 }