C# 数组集合<二> 双向链表和双向循环链表

本文介绍了C#中的数据结构——双向链表和双向循环链表,详细讲解了它们的概念,并提供了节点类、接口及具体链表类的实现代码,为后续的栈和队列学习奠定基础。
摘要由CSDN通过智能技术生成

前情提示:

上一篇总结了数据结构的基本概念,以及在C#下的一些基本实现Code。从这篇之后难度加大,代码量也增大了。分卷了。这一篇主要讲述双向链表和双向循环链表。

双向链表:

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。


双向循环链表:

双向循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。


节点类(DoubleLinkedListNode.cs)


 public class DoubleLinkedListNode<T>
    {
        //前驱
        private DoubleLinkedListNode<T> _nextDoubleLinkedListNode;
        private DoubleLinkedListNode<T> _prevDoubleLinkedListNode;

        //数据
        private T dataValue;

        /// <summary>
        ///     无参构造函数 该节点只有默认值,前驱和后继都 ——>null
        /// </summary>
        public DoubleLinkedListNode()
        {
            this.dataValue = default(T);
            this._nextDoubleLinkedListNode = null;
            this._prevDoubleLinkedListNode = null;
        }

        /// <summary>
        ///     构造方法:实例化该节点只有传入的data域,前驱和后继都指向null
        /// </summary>
        /// <param name="value"></param>
        public DoubleLinkedListNode(T value)
        {
            this._prevDoubleLinkedListNode = null;
            this.dataValue = value;
            this._nextDoubleLinkedListNode = null;
        }

        /// <summary>
        ///     构造函数:实例化一个正常的Node 数据域 前驱后继都有值
        /// </summary>
        /// <param name="value"></param>
        /// <param name="prev"></param>
        /// <param name="next"></param>
        public DoubleLinkedListNode(T value, DoubleLinkedListNode<T> prev, DoubleLinkedListNode<T> next)
        {
            this._prevDoubleLinkedListNode = prev;
            this.dataValue = value;
            this._nextDoubleLinkedListNode = next;
        }

        public DoubleLinkedListNode<T> PrevDoubleLinkedListNode
        {
            get { return this._prevDoubleLinkedListNode; }
            set { this._prevDoubleLinkedListNode = value; }
        }

        public T DataValue
        {
            get { return this.dataValue; }
            set { this.dataValue = value; }
        }

        public DoubleLinkedListNode<T> NextDoubleLinkedListNode
        {
            get { return this._nextDoubleLinkedListNode; }
            set { this._nextDoubleLinkedListNode = value; }
        }

        /// <summary>
        ///     Show 方法,调试用
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            T p = this._prevDoubleLinkedListNode == null ? default(T) : this._prevDoubleLinkedListNode.dataValue;
            T n = this._nextDoubleLinkedListNode == null ? default(T) : this._nextDoubleLinkedListNode.dataValue;
            string s = string.Format("Data:{0},Prev:{1},Next:{2}", this.dataValue, p, n);
            return s;
        }
    }



接口(ILinkList.cs)


 internal interface ILinkedList<T>
    {
        /// <summary>
        ///     头元素
        /// </summary>
        DoubleLinkedListNode<T> HeadDoubleLinkedListNode { get; }

        /// <summary>
        ///     尾元素
        /// </summary>
        DoubleLinkedListNode<T> EndDoubleLinkedListNode { get; }

        /// <summary>
        ///     在 LinkedList<(Of <(T>)>) 中指定的现有节点后添加指定的新节点。
        /// </summary>
        /// <param name="node"></param>
        /// <param name="newNode"></param>
        void AddAfter(DoubleLinkedListNode<T> node, DoubleLinkedListNode<T> newNode);

        /// <summary>
        ///     在 LinkedList<(Of <(T>)>) 中的现有节点后添加新的节点或值。
        /// </summary>
        /// <param name="node"></param>
        /// <param name="t"></param>
        void AddAfter(DoubleLinkedListNode<T> node, T t);

        /// <summary>
        ///     在 LinkedList<(Of <(T>)>) 中指定的现有节点前添加指定的新节点。
        /// </summary>
        /// <param name="node"></param>
        /// <param name="newNode"></param>
        void AddBefore(DoubleLinkedListNode<T> node, DoubleLinkedListNode<T> newNode);

        /// <summary>
        ///     在 LinkedList<(Of <(T>)>) 中指定的现有节点前添加包含指定值的新节点。
        /// </summary>
        /// <param name="node"></param>
        /// <param name="t"></param>
        void AddBefore(DoubleLinkedListNode<T> node, T t);

        /// <summary>
        ///     在 LinkedList<(Of <(T>)>) 的开头处添加包含指定值的新节点。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        DoubleLinkedListNode<T> AddFirst(T value);

        /// <summary>
        ///     在 LinkedList<(Of <(T>)>) 的开头处添加指定的新节点
        /// </summary>
        /// <param name="node"></param>
        void AddFirst(DoubleLinkedListNode<T> node);

        /// <summary>
        ///     在 LinkedList<(Of <(T>)>) 的结尾处添加包含指定值的新节点。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        DoubleLinkedListNode<T> AddLast(T value);

        /// <summary>
        ///     在 LinkedList<(Of <(T>)>) 的结尾处添加指定的新节点
        /// </summary>
        /// <param name="node"></param>
        void AddLast(DoubleLinkedListNode<T> node);

        /// <summary>
        ///     从 LinkedList<(Of <(T>)>) 中移除指定的节点。
        /// </summary>
        /// <param name="node"></param>
        bool Remove(DoubleLinkedListNode<T> node);

        /// <summary>
        ///     从 LinkedList<(Of <(T>)>) 中按索引删除节点。
        /// </summary>
        /// <param name="node"></param>
        bool Remove(int index);

        /// <summary>
        ///     移除头结点
        /// </summary>
        void RemoveHeadNode();

        /// <summary>
        ///     移除尾节点
        /// </summary>
        void RemoveEndNode();

        /// <summary>
        ///     从 LinkedList<(Of <(T>)>) 中查找第一个匹配项
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        DoubleLinkedListNode<T> Find(T value);

        /// <summary>
        ///     从 LinkedList<(Of <(T>)>) 中查找最后一个匹配项
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        DoubleLinkedListNode<T> FindLast(T value);

        /// <summary>
        ///     查询元素的索引
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        int IndexOf(T item);

        /// <summary>
        ///     能过索引得到元素的元素
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        T GetElementByIndex(int index);

        /// <summary>
        ///     通过索引得到节点对象
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        DoubleLinkedListNode<T> GetNodeByIndex(int index);
    }



双向链表类(DoubleLinkList.cs


public class DoubleLinkedList<T> : ILinkedList<T>
    {
        //前驱


        //后置
        private DoubleLinkedListNode<T> _endDoubleLinkedListNode;
        private DoubleLinkedListNode<T> _headDoubleLinkedListNode;

        //长度
        private int size;

        /// <summary>
        ///     判断链表是否是空的
        /// </summary>
        public bool IsEmpty
        {
            get { return this._headDoubleLinkedListNode == null; }
        }

        /// <summary>
        ///     链表中元素的个数
        /// </summary>
        public int Count
        {
            get
            {
                int i = 0;
                DoubleLinkedListNode<T> node = this._headDoubleLinkedListNode;
                while (node != null)
                {
                    ++ i;
                    node = node.NextDoubleLinkedListNode;
                }

                return i;

                //return this.size;
            }
        }

        /// <summary>
        ///     根据索引获取链表中的节点
        /// </summary>
        /// <param name="index">整型索引</param>
        /// <returns>节点</returns>
        public DoubleLinkedListNode<T> this[int index]
        {
            get
            {
                //链表头节点是空的
                if (this._headDoubleLinkedListNode == null)
                {
                    throw new Exception("链表是空的。");
                }
                //索引过小
                if (index < 0)
                {
                    throw new IndexOutOfRangeException();
                }
                //索引过大
                if (index >= this.Count)
                {
                    throw new IndexOutOfRangeException();
                }
                //取得头节点
                var current = new DoubleLinkedListNode<T>();
                //current = head;
                //int i = 0;
                遍历链表
                //while (true)
     
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值