双向链表也叫双链表
双向链表也叫双链表
每个节点都有两个指针,分别指向 直接前驱节点、直接后继节点
双向链表中任意一个节点,都可以通过通过它的前驱节点和后继节点,访问其他节点
节点如下
节点定义
ListNode
// 节点的值
T element;
// 前置节点
ListNode preNode;
// 后置节点
ListNode nextNode;
链表提供以下方法
项目 | Value |
---|---|
PushFront(T t) | 将元素插入到链表第一个位置 |
PushBack(T t) | 将元素插入到链表最后一个位置 |
Front() | 第一个节点 |
Back() | 最后一个节点 |
MakeEmpty() | 清空链表 |
IsEmpty() | 判断链表是否为空 |
Size() | 获取链表中数据个数 |
Find(T t) | 查找节点 |
Delete(T t) | 删除节点 |
Delete(ListNode node) | 删除节点 |
InsertAsNext(ListNode node, ListNode next) | 将 next 插入到 node 后 |
Begin() | 迭代器开始 |
End() | 迭代器结束 |
Deduplicate() | 无序链表删除重复元素 |
Uniquify() | 有序链表删除重复元素 |
List Traverse() | 迭代遍历获取所有元素 |
Swap(ListNode node1, ListNode node2) | 交换两个节点的值 |
Sort(Comparison comparison) | 排序,comparison 是比较函数 |
C# 代码实现如下
/// <summary>
/// 链表节点
/// </summary>
/// <typeparam name="T"></typeparam>
public class ListNode<T> where T : IComparable<T>
{
// 节点的值
private T element;
// 前置节点
private ListNode<T> preNode;
// 后置节点
private ListNode<T> nextNode;
public ListNode()
{
}
public ListNode(T v)
{
element = v;
}
public ListNode(T v, ListNode<T> pre, ListNode<T> next)
{
element = v;
preNode = pre;
nextNode = next;
}
public T Element
{
get { return element; }
set { element = value; }
}
public ListNode<T> PreNode
{
get { return preNode; }
set { preNode = value; }
}
public ListNode<T> NextNode
{
get { return nextNode; }
set { nextNode = value; }
}
}
/// <summary>
/// 链表迭代器
/// </summary>
/// <typeparam name="T"></typeparam>
public class LinkListIterator<T> where T : IComparable<T>
{
private ListNode<T> node;
public LinkListIterator(ListNode<T> node)
{
this.node = node;
}
public ListNode<T> Node
{
get { return node; }
}
public T Element
{
get
{
return node.Element;
}
}
/// <summary>
/// 重写 == 方法
/// </summary>
/// <param name="iteratorL"></param>
/// <param name="iteratorR"></param>
/// <returns></returns>
public static bool operator ==(LinkListIterator<T> iteratorL, LinkListIterator<T> iteratorR)
{
return null != iteratorL.node && null != iteratorR.node && iteratorL.node == iteratorR.node;
}
/// <summary>
/// 重写 != 方法
/// </summary>
/// <param name="iteratorL"></param>
/// <param name="iteratorR"></param>
/// <returns></returns>
public static bool operator !=(LinkListIterator<T> iteratorL, LinkListIterator<T> iteratorR)
{
return null == iteratorL.node || null == iteratorR.node || iteratorL.node != iteratorR.node;
}
/// <summary>
/// 重写 ++ 方法
/// </summary>
/// <param name="iterator"></param>
/// <returns></returns>
public static LinkListIterator<T> operator ++(LinkListIterator<T> iterator)
{
iterator.node = iterator.node.NextNode;
return iterator;
}
/// <summary>
/// 重写 -- 方法
/// </summary>
/// <param name="iterator"></param>
/// <returns></returns>
public static LinkListIterator<T> operator --(LinkListIterator<T> iterator)
{
iterator.node = iterator.node.PreNode;
return iterator;
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
/// <summary>
/// 链表
/// </summary>
/// <typeparam name="T"></typeparam>
public class LinkList<T> where T : IComparable<T>
{
/// <summary>
/// 头节点
/// </summary>
private ListNode<T> _header;
/// <summary>
/// 尾节点
/// </summary>
private ListNode<T> _trailer;
// 除去 头、尾,节点的个数
private int _size;
public LinkList()
{
// 为了减少操作上的复杂度
// 头节点和尾节点一直存在,添加、删除都是在 头节点、尾节点 中间操作
_header = new ListNode<T>();
_trailer = new ListNode<T>();
_header.PreNode = null;
_header.NextNode = _trailer;
_trailer.PreNode = _header;
_trailer.NextNode = null;
}
/// <summary>
/// 迭代器开始
/// </summary>
/// <returns></returns>
public LinkListIterator<T> Begin()
{
return new LinkListIterator<T>(_header.NextNode);
}
/// <summary>
/// 迭代器结束
/// </summary>
/// <returns></returns>
public LinkListIterator<T> End()
{
return new LinkListIterator<T>(_trailer);
}
/// <summary>
/// 第一个元素
/// </summary>
public ListNode<T> Front()
{
return Size() > 0 ? _header.NextNode : null;
}
/// <summary>
/// 最后一个元素
/// </summary>
public ListNode<T> Back()
{
return Size() > 0 ? _trailer.PreNode : null;
}
/// <summary>
/// 清空链表
/// </summary>
public void MakeEmpty()
{
_header.NextNode = _trailer;
_trailer.PreNode = _header;
_size = 0;
}
/// <summary>
/// 链表为空
/// </summary>
public bool IsEmpty()
{
return _header.NextNode == _trailer;
}
/// <summary>
/// 链表元素个数
/// </summary>
public int Size()
{
return _size;
}
/// <summary>
/// 查找元素指针位置
/// </summary>
public ListNode<T> Find(T t)
{
ListNode<T> temp = _header.NextNode;
while (temp != _trailer)
{
if (temp.Element.CompareTo(t) == 0)
{
return temp;
}
temp = temp.NextNode;
}
return null;
}
/// <summary>
/// 删除元素
/// </summary>
public void Delete(T t)
{
ListNode<T> node = Find(t);
Delete(node);
}
public void Delete(ListNode<T> node)
{
if (null != node)
{
node.PreNode.NextNode = node.NextNode;
node.NextNode.PreNode = node.PreNode;
--_size;
}
}
/// <summary>
/// 将元素插入到链表第一个位置
/// </summary>
/// <param name="t"></param>
public void PushFront(T t)
{
ListNode<T> newNode = new ListNode<T>(t);
InsertAsPre(_header.NextNode, newNode);
}
/// <summary>
/// 将元素插入到链表最后一个位置
/// </summary>
/// <param name="t"></param>
public void PushBack(T t)
{
ListNode<T> newNode = new ListNode<T>(t);
InsertAsPre(_trailer, newNode);
}
private void InsertAsPre(ListNode<T> node, ListNode<T> next)
{
InsertAsNext(node.PreNode, next);
}
/// <summary>
/// 将 next 插入到 node 后
/// </summary>
/// <param name="node"></param>
/// <param name="next"></param>
public void InsertAsNext(ListNode<T> node, ListNode<T> next)
{
if (node == _trailer)
{
return;
}
next.PreNode = node;
next.NextNode = node.NextNode;
node.NextNode.PreNode = next;
node.NextNode = next;
++_size;
}
/// <summary>
/// 无序链表删除重复元素
/// </summary>
public void Deduplicate()
{
for (ListNode<T> node = _header.NextNode; node != _trailer; node = node.NextNode)
{
for (ListNode<T> temp = node.NextNode; temp != _trailer; temp = temp.NextNode)
{
if (node.Element.CompareTo(temp.Element) == 0)
{
Delete(temp);
}
}
}
}
/// <summary>
/// 有序链表删除重复元素
/// </summary>
public void Uniquify()
{
ListNode<T> node = _header.NextNode;
while ( node != _trailer)
{
ListNode<T> next = node.NextNode;
if (next != _trailer && next.Element.CompareTo(node.Element) == 0)
{
Delete(next);
continue;
}
node = node.NextNode;
}
}
/// <summary>
/// 遍历
/// </summary>
public List<T> Traverse()
{
List<T> list = new List<T>();
for (LinkListIterator<T> iterator = Begin(); iterator != End(); ++iterator)
{
list.Add(iterator.Element);
}
return list;
}
/// <summary>
/// 交换两个节点位置
/// </summary>
public void Swap(ListNode<T> node1, ListNode<T> node2)
{
if (node1.NextNode == node2)
{
Swap(node1.PreNode, node2.NextNode, node1, node2);
}
else if (node2.NextNode == node1)
{
Swap(node2.PreNode, node1.NextNode, node2, node1);
}
else
{
Swap(node1.PreNode, node2.NextNode, node1, node2);
}
}
/// <summary>
/// 交换两个节点位置
/// </summary>
/// <param name="pre"></param>
/// <param name="next"></param>
/// <param name="node1"></param>
/// <param name="node2"></param>
private void Swap(ListNode<T> pre, ListNode<T> next, ListNode<T> node1, ListNode<T> node2)
{
Delete(node1);
Delete(node2);
InsertAsNext(pre, node2);
InsertAsPre(next, node1);
}
/// <summary>
/// 排序
/// </summary>
public void Sort(Comparison<T> comparison)
{
ListNode<T> begin = _header.NextNode;
if (null == begin || begin.NextNode == _trailer)
{
return;
}
for (ListNode<T> temp = begin.NextNode; temp != _trailer; temp = temp.NextNode)
{
T element = temp.Element;
ListNode<T> preNode = temp.PreNode;
while (preNode != _header.NextNode.PreNode && comparison(preNode.Element, element) > 0)
{
preNode.NextNode.Element = preNode.Element;
preNode = preNode.PreNode;
}
preNode.NextNode.Element = element;
}
}
}