【C#】自定义单向链表、双向链表及图解原理

参考:数组、单链表和双链表介绍 以及 双向链表的C/C++/Java实现

 单向链表:

由节点链接组成,在内存中不连续,每个节点包含节点自身的数据和下一节点的引用,节点链接方向是单向的,只能访问当前节点及下一节点,只能正向遍历,从头到尾遍历,增加、删除比较方便,查询比较麻烦

 

双向链表:

与单向链表相似, 由节点链接组成,在内存中不连续,每个节点包含节点自身的数据及上一节点、下一节点的引用,链接方向是双向的,可以访问当前节点及其上下节点,可以双向遍历,增删节点方便,还是不适合查询

C# 节点定义如下:

public class LinkNode<T>
{
    public T value;
    public LinkNode<T> lastNode;
    public LinkNode<T> nextNode;

    public LinkNode(T nodeValue, LinkNode<T> last, LinkNode<T> next)
    {
        value = nodeValue;
        lastNode = last;
        nextNode = next;
    }
}

参考文章中关于增加、删除节点的方法,研究了好半天,主要还是利用index下标作为索引,发现用C#的List、Stack、Queue,都可以更加高效的实现,链表反而更加繁琐,不能发挥出链表的特长

于是利用链表的特点写了两个增删方法(实际使用还是要根据具体需求,自定义合适的方法):

public class DoubleLink<T>
{
    //标记首尾节点
    public LinkNode<T> headtNode { get; private set; }
    public LinkNode<T> endNode { get; private set; }
    //有效节点个数
    public int count { get; private set; }

    public DoubleLink()
    {
        headtNode = new LinkNode<T>(default, null, null);
        endNode = new LinkNode<T>(default, headtNode, null);
        headtNode.nextNode = endNode;
        count = 0;
    }

    //在首节点之后插入节点
    public void AddAfterHead(T nodeValue)
    {
        LinkNode<T> newNode = new LinkNode<T>(nodeValue, headtNode, headtNode.nextNode);

        headtNode.nextNode.lastNode = newNode;
        headtNode.nextNode = newNode;

        count++;
    }

    //在尾节点之前插入节点
    public void AddBeforeEnd(T nodeValue)
    {
        LinkNode<T> newNode = new LinkNode<T>(nodeValue, endNode.lastNode, endNode);

        endNode.lastNode.nextNode = newNode;
        endNode.lastNode = newNode;

        count++;
    }

    //删除首节点后一个节点
    public void RemoveAfterHead()
    {
        LinkNode<T> node = headtNode.nextNode;

        node.nextNode.lastNode = headtNode;
        headtNode.nextNode = node.nextNode;

        count--;
    }

    //删除尾节点前一个节点
    public void RemoveBeforeEnd()
    {
        LinkNode<T> node = endNode.lastNode;

        node.lastNode.nextNode = endNode;
        endNode.lastNode = node.lastNode;

        count--;
    }

    //清空有效节点
    public void Clear()
    {
        headtNode.nextNode = endNode;
        endNode.lastNode = headtNode;
    }

}

测试:

public class Test : MonoBehaviour
{
    void Start()
    {
        DoubleLink<string> doubleLink = new DoubleLink<string>();

        doubleLink.AddAfterHead("1");
        doubleLink.AddAfterHead("0");
        doubleLink.AddBeforeEnd("2");
        doubleLink.AddBeforeEnd("3");

        LinkNode<string> node = doubleLink.headtNode;
        while (node != null)
        {
            Debug.Log(node.value);
            node = node.nextNode;
        }
        //打印结果:"Null;0;1;2;3;Null;"

        doubleLink.RemoveAfterHead();
        node = doubleLink.headtNode;
        while (node != null)
        {
            Debug.Log(node.value);
            node = node.nextNode;
        }
        //打印结果:"Null;1;2;3;Null;"

        doubleLink.RemoveBeforeEnd();
        node = doubleLink.headtNode;
        while (node != null)
        {
            Debug.Log(node.value);
            node = node.nextNode;
        }
        //打印结果:"Null;1;2;Null;"

        doubleLink.Clear();
        node = doubleLink.headtNode;
        while (node != null)
        {
            Debug.Log(node.value);
            node = node.nextNode;
        }
        //打印结果:"Null;Null;"

    }
}
发布了104 篇原创文章 · 获赞 74 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_39108767/article/details/103200352