C#資料結構-靜態連結串列

只愛宅zmy發表於2020-10-13
對於雙向連結串列中的節點,都包括一個向前、向後的屬性器用於指向前後兩個節點,對於引用型別,物件儲存的是指向記憶體片段的記憶體指標,那麼我們可以將其簡化看作向前向後的兩個指標。
現在我們將引用型別替換為值型別int,將鏈用陣列代替,向後的指標替換為陣列的下標,那麼此時的鏈我們稱為靜態連結串列(或者說是單向靜態連結串列)。
不多說,直接上程式碼(程式碼已做註解)
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}");
            }
        }
  }
測試:
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();
        }
    }
列印結果:

404258-20201013130149060-865023213.png
 
 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69983372/viewspace-2726568/,如需轉載,請註明出處,否則將追究法律責任。

相關文章