双向链表也叫双链表

双向链表也叫双链表

双向链表也叫双链表

每个节点都有两个指针,分别指向 直接前驱节点、直接后继节点

双向链表中任意一个节点,都可以通过通过它的前驱节点和后继节点,访问其他节点

节点如下

节点定义

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# 代码实现如下

csharp 复制代码
    /// <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;
            }
        }
    }
相关推荐
Fanxt_Ja2 天前
【LeetCode】算法详解#15 ---环形链表II
数据结构·算法·leetcode·链表
今后1232 天前
【数据结构】二叉树的概念
数据结构·二叉树
散1123 天前
01数据结构-01背包问题
数据结构
消失的旧时光-19433 天前
Kotlinx.serialization 使用讲解
android·数据结构·android jetpack
Gu_shiwww3 天前
数据结构8——双向链表
c语言·数据结构·python·链表·小白初步
苏小瀚3 天前
[数据结构] 排序
数据结构
_不会dp不改名_3 天前
leetcode_21 合并两个有序链表
算法·leetcode·链表
睡不醒的kun3 天前
leetcode算法刷题的第三十四天
数据结构·c++·算法·leetcode·职场和发展·贪心算法·动态规划
吃着火锅x唱着歌3 天前
LeetCode 978.最长湍流子数组
数据结构·算法·leetcode
Whisper_long3 天前
【数据结构】深入理解堆:概念、应用与实现
数据结构