C# data structure-static linked list

For the nodes in the doubly linked list, it includes a forward and backward attribute device to point to the two nodes before and after. For the reference type, the object stores the memory pointer to the memory segment, so we can simplify it as forward Two pointers backward.

Now we replace the reference type with the value type int, replace the chain with an array, and replace the backward pointer with the subscript of the array. Then the chain at this time is called a static linked list (or a one-way static linked list).

Not much to say, directly on the code (code has been annotated)

	public class Node<T>
    {
    
    

        public T data {
    
     get; set; }

        public int next {
    
     get; set; }

        public Node(T item)
        {
    
    
            data = item;
        }
    }
  	public class StaticLink<T>
    {
    
    
        public int count {
    
     get; set; } = 0;
        public Node<T>[] link {
    
     get; set; }
        public int minSize {
    
     get; set; } = 10;
        public int extendSize {
    
     get; set; } = 10;//扩容步长
        public StaticLink()
        {
    
    
            //第一个节点为空节点,不存储内容,同时,第一个节点的next存放备用链表的第一个节点(备用链表——数组内可以用于存储内容的处于空值时的节点连接成的表)
            //初始化,静态链表的长度为10;
            link = new Node<T>[minSize];
            for (int i = 0; i < minSize; i++)
            {
    
    
                //i=0时,由于链表为空,则备用链表的第一个节点也就是1
                link[i] = new Node<T>(default(T));
                link[i].next = i + 1;
            }
            //初始化,静态链表的结尾next 指向第一个节点(除头节点外)
            link[minSize - 1].next = 1;
            count++;
        }
        private int Malloc()
        {
    
    
            //取得静态链表-备用链表中的第一个节点(取出待用,存储内容)
            int i = link[0].next;
            if (i > 0)
            {
    
    
                //同时,移除备用链表的第一个节点,
                link[0].next = link[i].next;
                //取到链表的最后一个元素时,扩容。
                if (i >= minSize - 1)
                {
    
    
                    //todo 不翻倍扩容,采用定值步长扩容~
                    //todo 暂不实现
                }
            }
            return i;
        }
        /// <summary>
        /// 在链表的结尾附加
        /// </summary>
        /// <param name="node"></param>
        public void Append(T node)
        {
    
    
            Insert(count, node);
        }
        /// <summary>
        /// 指定位置插入节点
        /// </summary>
        /// <param name="index"></param>
        /// <param name="node"></param>
        public void Insert(int index, T node)
        {
    
    
            //要插入的节点需要在链表的范围内
            if (index > count || index < 1)
                throw new IndexOutOfRangeException("索引超出界限");
            //由于时插入节点,所以此处我们需要从备用链表取出一个空节点。
            int maxIndex = Malloc();
            int k = minSize - 1; 
            Node<T> newNode = new Node<T>(node);//创建一个节点

            if (count == 1)
                newNode.next = 0;
            else 
            {
    
    
                //取链表最后一个节点的next;
                for (int i = 1; i <= index -1; i++)
                {
    
    
                    k = link[k].next;
                }
                newNode.next = link[k].next;
                link[k].next = maxIndex;
            }
            link[maxIndex] = newNode;
            count++;
        }
        /// <summary>
        /// 根据索引删除
        /// </summary>
        /// <param name="index"></param>
        public void Del(int index)
        {
    
    
            //去除头节点,并判断索引要在链表范围内
            if (index < 1 || index > count)
                throw new IndexOutOfRangeException("索引超出界限");
            int k = minSize - 1;
            //通过链取得前一个节点 -时间复杂度O(n)
            for (int j = 1; j <= index - 1; j++)
            {
    
    
                k = link[k].next;
            }
            int beforeNodeNext = link[k].next;//获取前一个节点的next;
            link[k].next = link[beforeNodeNext].next;//跳过要删除的节点
            link[beforeNodeNext].next = link[0].next;//将释放除来的节点接入备用链
            link[0].next = beforeNodeNext;//将当前释放的节点放入到备用的第一个节点。-待用
            count--;
        }
        /// <summary>
        /// 展示链节点
        /// </summary>
        public void showAll()
        {
    
    
            for (int i = 1; i <= count; i++)
            {
    
    
                Console.WriteLine($"index:{link[i].next},data:{link[i].data}");
            }
        }
    }

test:

 	class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            StaticLink<string> link = new StaticLink<string>();
            link.Append("第一位");
            link.Append("第二位");
            link.Append("第三位");
            link.Insert(2,"第四位,插入到二的位置");
            link.Append("第五位");
            link.Append("第六位");
            link.Append("第七位");
            link.Del(6);

            link.showAll();

            Console.ReadLine();
        }
    }

Print result:
Insert picture description here

Insert picture description here

Guess you like

Origin blog.csdn.net/xuetian0546/article/details/109048888