双向链表

简介:

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

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

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;

        }

    }

}

 


作者:kissazi2 
出处:http://www.cnblogs.com/kissazi2/ 
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载:http://www.cnblogs.com/kissazi2/p/3193965.html

目录
相关文章
|
4天前
|
C语言
数据结构:5、链表之双向链表
数据结构:5、链表之双向链表
18 0
|
1月前
|
存储
【双向链表】数据结构双向链表的实现
【双向链表】数据结构双向链表的实现
|
3月前
|
Java
7.双向链表最佳实现
7.双向链表最佳实现
32 1
|
4月前
|
存储
双向链表的操作
双向链表的操作
|
5月前
|
存储 算法 搜索推荐
双向链表
双向链表是一种链式存储结构,每个节点包含两个指针,分别指向其前驱和后继。相比于单向链表,双向链表可以在常数时间内向前或向后遍历整个链表。因此,双向链表在需要频繁遍历链表的场景中具有优势。
33 7
|
5月前
10 双向链表
10 双向链表
18 0
|
6月前
【双向链表】
【双向链表】
16 0
|
存储 算法 C语言
循环链表及双向链表
循环链表及双向链表
82 0