C#实现双向链表
原文:http://www.cnblogs.com/skywang12345/p/3561803.html#a33 沒有C#版本的。。是不是很方。。不過圖和說明很好,引用一下
雙向鏈表
雙向鏈表(雙鏈表)是鏈表的一種。和單鏈表一樣,雙鏈表也是由節(jié)點(diǎn)組成,它的每個(gè)數(shù)據(jù)結(jié)點(diǎn)中都有兩個(gè)指針,分別指向直接后繼和直接前驅(qū)。所以,從雙向鏈表中的任意一個(gè)結(jié)點(diǎn)開始,都可以很方便地訪問它的前驅(qū)結(jié)點(diǎn)和后繼結(jié)點(diǎn)。一般我們都構(gòu)造雙向循環(huán)鏈表。
雙鏈表的示意圖如下:
表頭為空,表頭的后繼節(jié)點(diǎn)為"節(jié)點(diǎn)10"(數(shù)據(jù)為10的節(jié)點(diǎn));"節(jié)點(diǎn)10"的后繼節(jié)點(diǎn)是"節(jié)點(diǎn)20"(數(shù)據(jù)為10的節(jié)點(diǎn)),"節(jié)點(diǎn)20"的前繼節(jié)點(diǎn)是"節(jié)點(diǎn)10";"節(jié)點(diǎn)20"的后繼節(jié)點(diǎn)是"節(jié)點(diǎn)30","節(jié)點(diǎn)30"的前繼節(jié)點(diǎn)是"節(jié)點(diǎn)20";...;末尾節(jié)點(diǎn)的后繼節(jié)點(diǎn)是表頭。
雙鏈表刪除節(jié)點(diǎn)
刪除"節(jié)點(diǎn)30"
刪除之前:"節(jié)點(diǎn)20"的后繼節(jié)點(diǎn)為"節(jié)點(diǎn)30","節(jié)點(diǎn)30" 的前繼節(jié)點(diǎn)為"節(jié)點(diǎn)20"。"節(jié)點(diǎn)30"的后繼節(jié)點(diǎn)為"節(jié)點(diǎn)40","節(jié)點(diǎn)40" 的前繼節(jié)點(diǎn)為"節(jié)點(diǎn)30"。
刪除之后:"節(jié)點(diǎn)20"的后繼節(jié)點(diǎn)為"節(jié)點(diǎn)40","節(jié)點(diǎn)40" 的前繼節(jié)點(diǎn)為"節(jié)點(diǎn)20"。
?雙鏈表添加節(jié)點(diǎn)
?
在"節(jié)點(diǎn)10"與"節(jié)點(diǎn)20"之間添加"節(jié)點(diǎn)15"
添加之前:"節(jié)點(diǎn)10"的后繼節(jié)點(diǎn)為"節(jié)點(diǎn)20","節(jié)點(diǎn)20" 的前繼節(jié)點(diǎn)為"節(jié)點(diǎn)10"。
添加之后:"節(jié)點(diǎn)10"的后繼節(jié)點(diǎn)為"節(jié)點(diǎn)15","節(jié)點(diǎn)15" 的前繼節(jié)點(diǎn)為"節(jié)點(diǎn)10"。"節(jié)點(diǎn)15"的后繼節(jié)點(diǎn)為"節(jié)點(diǎn)20","節(jié)點(diǎn)20" 的前繼節(jié)點(diǎn)為"節(jié)點(diǎn)15"。
代碼
/// <summary>/// 雙向鏈表節(jié)點(diǎn)/// </summary>/// <typeparam name="T"></typeparam>public class BdNode<T>{public T Data { set; get; }public BdNode<T> Next { set; get; } public BdNode<T> Prev { set; get; } public BdNode(T val, BdNode<T> prev, BdNode<T> next){this.Data = val;this.Prev = prev;this.Next = next;}}鏈表操作:
public class DoubleLink<T>{//表頭private readonly BdNode<T> _linkHead;//節(jié)點(diǎn)個(gè)數(shù)private int _size;public DoubleLink(){_linkHead = new BdNode<T>(default(T), null, null);//雙向鏈表 表頭為空_linkHead.Prev = _linkHead;_linkHead.Next = _linkHead;_size = 0;}public int GetSize() => _size;public bool IsEmpty() => (_size == 0);//通過索引查找private BdNode<T> GetNode(int index){if (index < 0 || index >= _size)throw new IndexOutOfRangeException("索引溢出或者鏈表為空");if (index < _size / 2)//正向查找 {BdNode<T> node = _linkHead.Next;for (int i = 0; i < index; i++)node = node.Next;return node;}//反向查找BdNode<T> rnode = _linkHead.Prev;int rindex = _size - index - 1;for (int i = 0; i < rindex; i++)rnode = rnode.Prev;return rnode;}public T Get(int index) => GetNode(index).Data;public T GetFirst() => GetNode(0).Data;public T GetLast() => GetNode(_size - 1).Data;// 將節(jié)點(diǎn)插入到第index位置之前public void Insert(int index, T t){if (_size < 1 || index >= _size)throw new Exception("沒有可插入的點(diǎn)或者索引溢出了");if (index == 0)Append(_size, t);else{BdNode<T> inode = GetNode(index);BdNode<T> tnode = new BdNode<T>(t, inode.Prev, inode);inode.Prev.Next = tnode;inode.Prev = tnode;_size++;}}//追加到index位置之后public void Append(int index, T t){BdNode<T> inode;if (index == 0)inode = _linkHead;else{index = index - 1;if (index < 0)throw new IndexOutOfRangeException("位置不存在");inode = GetNode(index);}BdNode<T> tnode = new BdNode<T>(t, inode, inode.Next);inode.Next.Prev = tnode;inode.Next = tnode;_size++;}public void Del(int index){BdNode<T> inode = GetNode(index);inode.Prev.Next = inode.Next;inode.Next.Prev = inode.Prev;_size--;}public void DelFirst() => Del(0);public void DelLast() => Del(_size - 1); public void ShowAll(){Console.WriteLine("******************* 鏈表數(shù)據(jù)如下 *******************");for (int i = 0; i < _size; i++)Console.WriteLine("(" + i + ")=" + Get(i));Console.WriteLine("******************* 鏈表數(shù)據(jù)展示完畢 *******************\n");}}測試:
DoubleLink<int> dlink = new DoubleLink<int>();// 創(chuàng)建雙向鏈表Console.WriteLine("將 20 插入到表頭之后");dlink.Append(0, 10); dlink.ShowAll();Console.WriteLine("將 40 插入到表頭之后");dlink.Append(1, 30); dlink.ShowAll();Console.WriteLine("將 10 插入到表頭之前");dlink.Insert(0, 40); dlink.ShowAll();Console.WriteLine("將 30 插入到第一個(gè)位置之前");dlink.Insert(1, 20); dlink.ShowAll();Console.WriteLine("展示第一個(gè):" + dlink.GetFirst()); Console.WriteLine("刪除第一個(gè)");dlink.DelFirst();Console.WriteLine("展示第一個(gè):" + dlink.GetFirst());Console.WriteLine("展示最后一個(gè):" + dlink.GetLast());Console.WriteLine("刪除最后一個(gè)");dlink.DelLast();Console.WriteLine("展示最后一個(gè):" + dlink.GetLast());dlink.ShowAll();Console.ReadKey();?
轉(zhuǎn)載于:https://www.cnblogs.com/ylsforever/p/6510528.html
與50位技術(shù)專家面對面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
- 上一篇: 20155313 2016-2017-2
- 下一篇: 用C#操作word替换字符,用spire