双向链表

简介:

基本上,我们可以认为双向链表是单链表的一个改进。这个改进一个有益的地方就是,双链表不必像单链表一样,为了查找一个元素,沿着链表的特定一个方向,从头遍历到尾。通过双链表,我们可以沿着正反两个方向对链表内的元素进行查找。

双链表的结点与单链表(循环链表)的稍稍有点不同,主要的不同就在与,双链表的节点多出了一个连接前一个节点的字段(详见灰色部分)。如下所示

class DulNode<T>

{

    private T data;

    /// <summary>

    /// 数据域

    /// </summary>

    public T Data

    {

        get {return data;}

        set { data = value;}

    }

 

 

    private DulNode<T> next;

    /// <summary>

    /// 引用域

    /// </summary>

    public DulNode<T> Next

    {

        get {return next;}

        set { next = value;}

    }

    private DulNode<T> prior;

 

    public DulNode<T> Prior

    {

        get {return prior;}

        set { prior = value;}

    }

   

    //头结点构造函数

    public DulNode(DulNode<T> next)

        :this(default(T),null, next)

    {

    }

    //头结点构造函数

    public DulNode(T data)

        :this(data,null,null)

    {

    }

    //普通结点构造函数

    public DulNode(T data,DulNode<T> prior, DulNode<T> next)

    {

        this.Data = data;

        this.Next = next;

        this.Prior = prior;

    }

    /// <summary>

    /// 空构造函数

    /// </summary>

    public DulNode()

        :this(default(T),null,null)

    {

    }

    //尾结点构造函数

    public DulNode(T data,DulNode<T> prior)

        :this(data, prior,null)

    {

 

    }

 

}

 

我们初始化一个双向链表,以便让大家更加直观的了解到双向链表中头结点和尾节点的不同。这个链表有四个节点,我们分别用0,1,2,3填充这个链表。

头节点如下所示:(其中next代表连接后一个节点的后导节点,prior代表连接前一个节点的前导节点)

image

尾节点如下所示

image

普通的节点如下所示:

image

 

双向链表具体的实现如下所示

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace DataStructure

{

    class DulList<T>: IListDS<T>

    {

        class DulNode<T>

        {

            private T data;

            /// <summary>

            /// 数据域

            /// </summary>

            public T Data

            {

                get {return data;}

                set { data = value;}

            }

 

 

            private DulNode<T> next;

            /// <summary>

            /// 引用域

            /// </summary>

            public DulNode<T> Next

            {

                get {return next;}

                set { next = value;}

            }

            private DulNode<T> prior;

 

            public DulNode<T> Prior

            {

                get {return prior;}

                set { prior = value;}

            }

 

            //头结点构造函数

            public DulNode(DulNode<T> next)

                :this(default(T),null, next)

            {

            }

            //头结点构造函数

            public DulNode(T data)

                :this(data,null,null)

            {

            }

            //普通结点构造函数

            public DulNode(T data, DulNode<T> prior, DulNode<T> next)

            {

                this.Data = data;

                this.Next = next;

                this.Prior = prior;

            }

            /// <summary>

            /// 空构造函数

            /// </summary>

            public DulNode()

                :this(default(T),null,null)

            {

            }

            //尾结点构造函数

            public DulNode(T data, DulNode<T> prior)

                :this(data, prior,null)

            {

 

            }

 

        }

 

        private DulNode<T> Head;

 

        public DulList(T[] t)

        {

            this.Head =new DulNode<T>(t[0]);

            DulNode<T> Current;

            Current = Head;

            for(int i =1; i < t.Length; i++)

            {

                DulNode<T> newNode =new DulNode<T>(t[i]);

                //设置前一个连接点

                newNode.Prior = Current;

                //当前节点的next设置为新的节点

                Current.Next = newNode;

                //将当前节点的引用域指向新的节点

                Current = newNode;

            }

        }

 

        public DulList()

        {

        }

 

        publicint Lenth

        {

            get {returnthis.GetLength();}

        }

 

        public States Append(T item)

        {

            //(1)头结点没有

            if(Head ==null)

            {

                Head =new DulNode<T>(item);

                return States.Success;

            }

            //(2)正常的插入情况

            DulNode<T> Last;

            Last = Head;

            //遍历到最后一个结点,在最后一个结点附加上

            while(null!= Last.Next)

            {

                Last = Last.Next;

            }

            DulNode<T> newNode =new DulNode<T>(item);

            Last.Next = newNode;

            newNode.Prior = Last;

            return States.Success;

        }

 

        publicvoid Clear()

        {

            Head =null;

        }

 

        public T Delete(int index,out States states)

        {

            bool isIndexTrue = index <0|| index >=this.GetLength();

            if(IsEmpty()==true|| isIndexTrue)

            {

                states = States.Fail;

                returndefault(T);

            }

            //找到指定的结点

            DulNode<T> Current = Head;

            DulNode<T> Previous = Head;

            int Count =0;

            while(Count != index && Current.Next !=null)

            {

                Previous = Current;

                Current = Current.Next;

                Count++;

            }

            T ValueToDel = Current.Data;

            //是否是头结点

            if(Count ==0)

            {

                Head = Current.Next;

                Current.Next.Prior =null;

            }

            //是否是普通的结点

            if(Count !=0&& Current.Next !=null)

            {

                Previous.Next = Current.Next;

                Current.Next.Prior = Previous;

            }

            //是否是最后一个结点

            if(Count !=0&& Current.Next ==null)

            {

                Previous.Next =null;

            }

 

            //删除结点

            states = States.Success;

            return ValueToDel;

        }

 

        public T GetElem(int i)

        {

            if(<0|| i >=this.GetLength())

            {

                returndefault(T);

            }

            if(IsEmpty()==true)

            {

                returndefault(T);

            }

 

            DulNode<T> Last = Head;

            int Count =0;

            while(Count != i && Last.Next !=null)

            {

                Last = Last.Next;

                Count++;

            }

            return Last.Data;

        }

 

        publicint GetLength()

        {

            if(Head ==null)

            {

                return0;

            }

            DulNode<T> Last;

            Last = Head;

            int Count =0;

            while(Last.Next !=null)

            {

                Last = Last.Next;

                Count++;

            }

            return++Count;

        }

 

        public States Insert(T item,int index)

        {

            bool isIndexTrue = index <0|| index >this.GetLength();

            if(isIndexTrue)

            {

                return States.Fail;

 

            }

            //如果链表为空

            if(IsEmpty()==true)

            {

                Head.Data = item;

            }

            //如果是第一个结点

            if(index ==0)

            {

                DulNode<T> NewNode =new DulNode<T>(item);

                NewNode.Next = Head;

                Head.Prior = NewNode;

                Head = NewNode;

                return States.Success;

            }

            //如果是普通的结点

            DulNode<T> Previous = Head;//当前节点的前一个

            int Count =0;

            while(Count != index -1&& Previous.Next !=null)//因为要取到插入位置的前一个节点所以用Count != index-1的判断

            {

                Previous = Previous.Next;

                Count++;

            }

            //如果是最后一个结点

            if(this.GetLength()== index)

            {

                DulNode<T> NewNode =new DulNode<T>(item);

                Previous.Next = NewNode;

                NewNode.Prior = Previous;

                return States.Success;

            }

            if(Count == index -1)

            {

                DulNode<T> NewNode =new DulNode<T>(item);

                DulNode<T> Current = Previous.Next;

                NewNode.Next = Current;

                Current.Prior = NewNode;

                NewNode.Prior = Previous;

                Previous.Next = NewNode;

            }

 

            return States.Success;

        }

 

        publicbool IsEmpty()

        {

            return Head ==null?true:false;

        }

 

        publicint Locate(T value,out States states)

        {

            if(IsEmpty()==true)

            {

                states = States.Fail;

                return0;

            }

 

            DulNode<T> Last = Head;

            int Index =0;

            while(Last.Next !=null&&(!value.Equals(Last.Data)))

            {

                Last = Last.Next;

                Index++;

            }

            states = States.Success;

            return Index;

        }

    }

}

 

本文转自陈哈哈博客园博客,原文链接 http://www.cnblogs.com/kissazi2/p/3193965.html如需转载请自行联系原作者

kissazi2
相关文章
|
存储 监控 C语言
西门子S7-1200编程实例,关断延迟定时器指令如何使用?
在西门子S7-1200中有四种类型的定时器:TON接通延迟定时器、TONR保持型接通延迟定时器、TOF关断延迟定时器、TP脉冲定时器。
西门子S7-1200编程实例,关断延迟定时器指令如何使用?
|
数据采集 数据可视化 搜索推荐
|
9月前
|
Java
Java实现贪吃蛇游戏
本文介绍了如何使用Java实现一个简单的贪吃蛇游戏。
328 4
|
11月前
|
Web App开发 算法 安全
等保、密评专用—双算法SSL证书
等保和密评专用双算法SSL证书结合国际(如RSA)和国密(如SM2)算法,确保数据传输安全与合规,同时兼容国内外浏览器,满足网络安全等级保护和商用密码应用安全性评估要求。该证书增强数据加密,提高安全性,适用于各类网站和应用。
|
10月前
|
存储 监控 数据挖掘
智能流程管理:CRM系统助力订单与回款自动化
在现代企业管理中,CRM系统不仅是客户信息的存储库,更是提升运营效率的关键工具。通过订单管理自动化、回款跟踪自动化、财务与CRM集成、数据分析及报告,企业能减少人为错误,优化现金流,提高响应速度,增强客户满意度。CRM系统的全面应用显著提升了企业的内部效率和外部竞争力,成为推动持续发展的重要力量。
|
9月前
|
人工智能 语音技术 iOS开发
MiniCPM-o 2.6:面壁智能开源多模态大模型,仅8B参数量就能媲美GPT-4o,支持实时交互,在ipad等终端设备上运行
MiniCPM-o 2.6 是面壁智能开源的多模态大模型,支持视觉、语音和多模态直播,性能媲美GPT-4o,能够在端侧设备上高效运行。
693 10
MiniCPM-o 2.6:面壁智能开源多模态大模型,仅8B参数量就能媲美GPT-4o,支持实时交互,在ipad等终端设备上运行
|
9月前
|
搜索推荐 数据挖掘 BI
产品电子画册制作软件哪个好?排名前6的软件都在这里
简要评测Adobe InDesign、草料二维码、创客贴、样本云、云展网、名编辑6款常见的产品电子画册制作工具,让你在选择出更适合自己的工具
|
11月前
|
人工智能 Java API
ChatClient:探索与AI模型通信的Fluent API
【11月更文挑战第22天】随着人工智能(AI)技术的飞速发展,越来越多的应用场景开始融入AI技术以提升用户体验和系统效率。在Java开发中,与AI模型通信成为了一个重要而常见的需求。为了满足这一需求,Spring AI引入了ChatClient,一个提供流畅API(Fluent API)的客户端,用于与各种AI模型进行通信。本文将深入探讨ChatClient的底层原理、业务场景、概念、功能点,并通过Java代码示例展示如何使用Fluent API与AI模型进行通信。
305 8
|
安全 Ubuntu Linux
在Linux中,如何进行系统升级?
在Linux中,如何进行系统升级?
|
安全 云栖大会 云计算
首批Well-Architected生态合作伙伴揭晓,齐聚2024云栖大会
在帮助企业客户上好云、用好云、管好云的道路上,阿里云始终坚持开放合作的理念,不断寻求与优质的生态伙伴深化合作,携手共建Well-Architected技术与服务方案。在今年的云栖大会上,共七家合作伙伴企业荣获首批「Well-Architected阿里云卓越架构生态合作伙伴」认证。
525 2