C# 双向链表的实现

C#数据结构——双向链表的实现

双向链表的说明: 在单向链表的存储结构中,只有一个指示直接后继的指针域,由此从某个节点出发只能顺指针往后查询其他节点。如果要查询节点的直接前驱,则需要从表头指针出发。为了克服单链表这种单向性的缺点,可以使用双向链表。在双向链表的节点中有两个指针域,其一指向直接前驱,另一个指向直接后继。

关键技术

双向链表的算法描述和单向链表基本相同,具体基础知识可以参照实例“链表的实现”,但是双向链表在删除和插入时与单向链表有很大的不同。双向链表在删除节点时,不但要修改节点的直接后继指针,还要同时修改节点的直接前驱指针。在插入时更是要修改插入节点的前驱和后继的两个方向上的指针。

设计过程

(1)打开Visual Studio 开发环境,新建一个类库项目,命名为BothChainTable。
(2)将“Class1.cs”文件重命名为“DoubleLink.cs”。
(3)程序主要代码如下:
构造函数代码如下:

public Objects(int num, string Name, int count)//构造函数
{
    //获取参数值
    number = num;
    name = Name;
    counter = count;
}
public int Number//定义变量
{
    get//访问器
    {
        return number;//获取值
    }
    set //访问器
    {
        number = value; //设置值
    }
}
public string Name
{
    get
    {
        return name;
    }
    set
    {
        name = value;
    }
}
public int Counter
{
    get
    {
        return counter;
    }
    set
    {
        counter = value;
    }
}

定义链表中的节点的实现代码如下:

public class ListNode//类
{
    public ListNode(Objects bugs)                   //构造函数
    {
        goods = bugs;
    }
    public ListNode Previous;   //前一个
    public ListNode Next;   //后一个
    public ListNode next
    {
        get
        {
            return Next;
        }
        set
        {
            Next = value;
        }
    }
    public Objects goods;//值
    public Objects Goods
    {
        get
        {
            return goods;
        }
        set
        {
            goods = value;
        }
    }
}

定义链表类的实现代码如下:

public Clists()                                 //构造函数
{
    ListCountValue = 0;                             //初始化
    Head = null;
    Tail = null;
}
private string clistname = "";                      //表名
public string ClistName
{
    get
    {
        return clistname;
    }
    set
    {
        clistname = value;
    }
}
private ListNode Head;                          //头指针
private ListNode Tail;                          //尾指针
private ListNode Current;                           //当前指针
public ListNode current
{
    get
    {
        return Current;
    }
    set
    {
        Current = value;
    }
}
private int ListCountValue;                         //链表数据的个数

在链表尾部添加数据的实现代码如下:

public void Append(Objects DataValue)
{
    ListNode NewNode = new ListNode(DataValue);
    if (IsNull())                               //如果头指针为空
    {
        Head = NewNode;
        Tail = NewNode;
    }
    else
    {
        Tail.Next = NewNode;
        NewNode.Previous = Tail;
        Tail = NewNode;
    }
    Current = NewNode;
    ListCountValue += 1;                            //链表数据个数加一
}

删除当前数据的实现代码如下:

public void Delete()
{
    if (!IsNull())                                  //若为空链表
    {
        if (IsBof())                                //若删除头
        {
            Head = Current.Next;
            Current = Head;
            ListCountValue -= 1;
            return;
        }
        if (IsEof())                                //若删除尾
        {
            Tail = Current.Previous;
            Tail.next = null;
            Current = Tail;
            ListCountValue -= 1;
            return;
        }
        Current.Previous.Next = Current.Next;
        Current = Current.Previous;
        ListCountValue -= 1;
        return;
    }
}
public void MoveNext()
{
    if (!IsEof()) Current = Current.Next;                   //向后移动一个数据
}
public void MovePrevious()
{
    if (!IsBof()) Current = Current.Previous;               //向前移动一个数据
}
public void MoveFrist()
{
    Current = Head;                             //移动到第一个数据
}
public void MoveLast()
{
    Current = Tail;                             //移动到最后一个数据
}
public bool IsNull()
{
    if (ListCountValue == 0)                        //判断是否为空链表
    return true;
    else
    return false;
}
public bool IsEof()
{
    if (Current == Tail)                            //判断是否到达尾部
    return true;
    else
    return false;
}
public bool IsBof()
{
    if (Current == Head)                            //判断是否到达头部
     return true;
    else
    return false;
}
public Objects GetCurrentValue()                        //获取值
{
    return Current.goods;
}
public int ListCount
{
    get
    {
        return ListCountValue;                      //取得链表的数据个数
    }
}

清空链表的实现代码如下:

public void Clear()
{
    MoveFrist();
    while (!IsNull())
    {
        Delete();                               //若不为空链表,从尾部删除
    }
}
public void Insert(Objects DataValue)                   //在当前位置前插入数据
{
    ListNode NewNode = new ListNode(DataValue);
    if (IsNull())
    {
        Append(DataValue);                      //为空表,则添加
        return;
    }
    if (IsBof())
    {
        //为头部插入
        NewNode.Next = Head;
        Head.Previous = NewNode;
        Head = NewNode;
        Current = Head;
        ListCountValue += 1;
        return;
    }
  NewNode.Next = Current;                           //中间插入
    NewNode.Previous = Current.Previous;
    Current.Previous.Next = NewNode;
    Current.Previous = NewNode;
    Current = NewNode;
    ListCountValue += 1;
}

升序插入的实现代码如下:

public void InsertAscending(Objects InsertValue)
{
    //参数:InsertValue 插入的数据
    if (IsNull())                                   //为空链表
    {
        Append(InsertValue);                        ///添加
        return;
    }
    MoveFrist();                                //移动到头
    if ((InsertValue.Number < GetCurrentValue().Number))
    {
        Insert(InsertValue);                            //满足条件,则插入,退出
        return;
    }
while (true)
    {
        if (InsertValue.Number < GetCurrentValue().Number)
        {
            Insert(InsertValue);                        //满足条件,则插入,退出
            break;
        }
        if (IsEof())
        {
            Append(InsertValue);                    //尾部添加
            break;
        }
        MoveNext();                             //移动到下一个指针
    }
}

降序插入的实现代码如下:

public void InsertUnAscending(Objects InsertValue)
{
    //参数:InsertValue 插入的数据
    if (IsNull())                                   //为空链表
    {
        Append(InsertValue);                        //添加
        return;
    }
    MoveFrist();                                //移动到头
    if (InsertValue.Number > GetCurrentValue().Number)
    {
        Insert(InsertValue);                            //满足条件,则插入,退出
        return;
    }
while (true)
    {
        if (InsertValue.Number > GetCurrentValue().Number)
        {
            Insert(InsertValue);                        //满足条件,则插入,退出
            break;
        }
        if (IsEof())
        {
            Append(InsertValue);                    //尾部添加
            break;
        }
        MoveNext();                             //移动到下一个指针
    }
}

技巧与心得

一个算法应该具有以下特点:

  • 有穷性:一个算法必须在执行有穷多个计算机步骤后终止;
  • 确定性:一个算法给出的每个计算步骤,必须是有精确定义、无二义性;
  • 有效性:算法中的每一个步骤必须有效地执行,并能得到确定结果;
  • 输入:一个算法中可以没有输入,也可以有一个或多个输入信息。这些输入信息是算法所须的初始数据;
  • 输出:一个算法应有一个或多个输出,一个算法得到的结果(中间结果或最后结果)就是算法的输出,没有输出的算法是没有意义的。
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洋洋脚踝的金铃响了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值