双向链表也叫双链表

双向链表也叫双链表

双向链表也叫双链表

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

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

节点如下

节点定义

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;
            }
        }
    }
相关推荐
Lucky_ldy2 小时前
数据结构从入门到精通:顺序表
数据结构·链表
熬夜敲代码的猫2 小时前
AVL树(C++详解版)
数据结构·c++·算法
并不喜欢吃鱼3 小时前
从零开始 C++-----十一【C++ 数据结构】红黑树全解析:从定义到工程实现(一文搞定,十分详细)
开发语言·数据结构·c++
星恒随风3 小时前
C语言数据结构排序算法详解(上):从插入排序、希尔排序到选择排序、堆排序
c语言·数据结构·笔记·学习·排序算法
迈巴赫车主3 小时前
蓝桥杯21247弹跳鞋java
java·开发语言·数据结构·算法·职场和发展·蓝桥杯
Cthy_hy4 小时前
Python算法竞赛:集合去重+字典映射 核心用法一站式整理
数据结构·python·算法
happymaker06264 小时前
LeetCodeHot100——盛水最多的容器
数据结构·算法·leetcode·双指针·hot100
过期动态4 小时前
【LeetCode 热题 100】三数之和
java·数据结构·算法·leetcode·职场和发展·排序算法
一切皆是因缘际会4 小时前
AI高速迭代下的技术风险与理性突围
大数据·数据结构·人工智能·架构
代码中介商5 小时前
B+树:数据库索引的终极奥秘
数据结构