C# 循环单链表

和单链表差不多,只不过添加一个尾指针,指向最后一个元素,头节点就不用公开了,默认一个私有字段即可,可以快速获取最后一个元素和第一个元素,时间复杂度为O(1)。

节点类


/// <summary>
/// 节点
/// </summary>
public class Node<T>
{
    private T data;
    private Node<T> next;

    public T Data
    {
        get
        {
            return data;
        }
        set
        {
            data = value;
        }
    }

    public Node<T> Next
    {
        get
        {
            return next;
        }

        set
        {
            next = value;
        }
    }

    public Node()
    {
        data = default;
        next = null;
    }
    public Node(T data, Node<T> next)
    {
        this.data = data;
        this.next = next;
    }
    public Node(T data)
    {
        this.data = data;
        this.next = null;
    }
    public Node(Node<T> next)
    {
        this.next = next;
    }
}

QCircularLinkedList:
添加了Count属性


public class QCircularLinkedList<T>
{
    /// <summary>
    /// 头结点
    /// </summary>
    private Node<T> head;

    /// <summary>
    /// 尾结点
    /// </summary>
    private Node<T> rear;

    /// <summary>
    /// 只暴露一个尾结点属性即可
    /// </summary>
    public Node<T> Rear
    {
        get { return rear; }
        set { rear = value; }
    }

    public QCircularLinkedList()
    {
        head = null;
        rear = head;
    }

    public QCircularLinkedList(T head = default)
    {
        this.head = new Node<T>(head);
        this.head.Next = this.head;
        this.rear = this.head;
    }

    private int count;

    public int Count
    {
        get { return count; }
        set { count = value; }
    }

    public bool IsEmpty()
    {
        return head == null || head.Next == head;
    }

    public void Clear()
    {
        head.Next = head;
        rear = head;
        count = 0;
    }

    /// <summary>
    /// 在末尾添加数据
    /// </summary>
    /// <param name="data"></param>
    public void Append(T data)
    {
        if (head == null)
        {
            head = new Node<T>();
            head.Next = head;
            rear = head;
        }

        Node<T> p = head;

        while (p.Next != head)
        {
            p = p.Next;
        }

        var node = new Node<T>(data);
        p.Next = node;
        node.Next = head;
        rear = node;

        count++;
    }

    /// <summary>
    /// 插入索引元素前面,所以不会插到最后,不用更新rear
    /// </summary>
    /// <param name="index"></param>
    /// <param name="data"></param>
    public void Insert(int index, T data)
    {
        if (index < 1 || IsEmpty())
        {
            //throw new System.Exception("插入位置不允许或链表为空!");
            return;
        }

        Node<T> p = head;
        int i = 1;

        while (p.Next != head && i < index)
        {
            p = p.Next;
            ++i;
        }

        if (p.Next == head || i > index)
        {
            //throw new System.Exception("插入位置不正确!");
            return;
        }

        Node<T> node = new(data);
        node.Next = p.Next;
        p.Next = node;

        count++;
    }

    public T GetItem(int index)
    {
        if (index < 1 || IsEmpty())
        {
            //throw new System.Exception("获取位置不允许或链表为空!");
            return default;
        }

        Node<T> p = head.Next;
        int i = 1;

        while (p != head && i < index)
        {
            p = p.Next;
            ++i;
        }

        if (p == head || i > index)
        {
            //throw new System.Exception("未找到元素!");
            return default;
        }

        return p.Data;
    }

    public void Delete(int index)
    {
        if (index < 1 || IsEmpty())
        {
            //throw new System.Exception("删除位置不允许或链表为空!");
            return;
        }

        Node<T> p = head;
        int i = 1;

        while (p.Next != head && i < index)
        {
            p = p.Next;
            ++i;
        }

        if (p == head || i > index)
        {
            //throw new System.Exception("未找到元素!");
            return;
        }

        p.Next = p.Next.Next;

        //如果删除的是最后一个元素,更新rear
        if (p.Next == head)
        {
            rear = p;
        }

        count--;
    }

    /// <summary>
    /// 整表创建:头插
    /// </summary>
    /// <param name="n"></param>
    public void CreatListHead(int n, T data = default)
    {
        head = new Node<T>();
        head.Next = head;
        rear = head;
        int i = 1;

        Node<T> p = default;
        while (i <= n)
        {
            p = new Node<T>(data);
            p.Next = head.Next;
            head.Next = p;
        }
        rear = p;

        count = n;
    }

    /// <summary>
    /// 整表创建:尾插
    /// </summary>
    /// <param name="n"></param>
    public void CreatListEnd(int n, T data = default)
    {
        head = new Node<T>();      
        head.Next = head;
        rear = head;

        Node<T> p = head;
        int i = 1;

        while (i <= n)
        {
            p.Next = new Node<T>(data);
            p = p.Next;
        }

        p.Next = head;
        rear = p;
        count = n;
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值