1. 程式人生 > >【C#】【資料結構】002-線性表:單鏈表

【C#】【資料結構】002-線性表:單鏈表

C#資料結構:單鏈表

  • 1、自定義單鏈表結構:
  • 單鏈節點類
using System.Collections;
using System.Collections.Generic;
using UnityEngine;




/// <summary>
/// 單鏈表節點
/// </summary>
/// <typeparam name="T"></typeparam>
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(T);
        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;
    }
       
}
  • 單鏈表類

/// <summary>
/// 單鏈表
/// </summary>
/// <typeparam name="T"></typeparam>
public class LinkList<T> 
{
    private Node<T> head;//頭指標

    public LinkList()
    {
        head = new Node<T>();
    }

    

    //判空
    public bool IsEmpty()
    {
        return head.Next == null;
    }

    //新增操作
    public void Add(T item,bool isHeadAdd=false)
    {
        if(isHeadAdd)
        {
            Insert(item, 0);
            return;
        }

        if(IsEmpty())
        {
            head.Next = new Node<T>(item);
        }
        else
        {
            Node<T> temp = head;
            while (true)
            {
                if(temp.Next!=null)
                {
                    temp = temp.Next;
                }
                else
                {
                    break;
                }
            }
            temp.Next = new Node<T>(item);
        }
    }


    //插入操作
    public void Insert(T item, int index)
    {
        if (index < 0 || index > GetLength()) //可以插到尾部
        {
            Debug.LogError("index不合法!");
            return;
        }

        Node<T> newNode = new Node<T>(item);
        if(index==0)//頭插入
        {
            Node<T> temp = head.Next;
            head.Next = newNode;
            newNode.Next = temp;
        }
        else
        {
            Node<T> temp = head;
            for (int i = 0; i < index ; i++)
            {
                temp = temp.Next;
            }
            Node<T> preNode = temp;
            Node<T> currteNode = temp.Next;
            preNode.Next = newNode;
            newNode.Next = currteNode;
        }
    }

    

    //刪除操作
    public T Delete(int index)
    {
        T data = default(T);
        if (index < 0 || index > GetLength()-1)
        {
            Debug.LogError("index不合法!");
            return data;
        }

        Node<T> temp = head;
        for (int i = 0; i < index; i++)
        {
            temp = temp.Next;
        }
        Node<T> preNode = temp;
        Node<T> currteNode = temp.Next;
        preNode.Next = currteNode.Next;
        data = currteNode.Data;
        currteNode = null;
        return data;
    }


    public T this[int index]//索引器訪問值
    {
        get
        {
            T data = default(T);
            if (index < 0 || index > GetLength() - 1)
            {
                Debug.LogError("index不合法!");
                return data;
            }

            Node<T> temp = head;
            for(int i=0;i<=index;i++)
            {
                temp = temp.Next;
            }
            return temp.Data;
        }
    }

    //訪問index位置的值
    public T GetElem(int index)
    {
        return this[index];
    }


    //連結串列長度
    public int GetLength()
    {
        int length = 0;
        if(!IsEmpty())
        {
            Node<T> temp = head;
            while (true)
            {
                if (temp.Next != null)
                {
                    length++;
                    temp = temp.Next;                    
                }
                else
                {
                    break;
                }
            }
        }
        return length;
    }

   
    //定址
    public int Locate(T value)//有相同值的返回首次查詢到的元素的index
    {
        if(!IsEmpty())
        {
            int index = 0;
            Node<T> temp = head;
            while(true)
            {
                if(temp.Next!=null)
                {
                    temp = temp.Next;
                    if (temp.Data.Equals(value))
                    {
                        return index;
                    }
                    index++;
                }
                else
                {
                    break;
                }
            }
            Debug.Log("無此值!");
            return -1;
        }
        else
        {
            Debug.Log("空表!");
            return -1;
        }
        
    }

    //清空操作
    public void Clear()
    {
        head.Next = null;
    }

    //顯示錶元素
    public void Display()
    {
        if (IsEmpty())
        {
            Debug.Log("表空");
            return;
        }
        Debug.Log("表中的值:");

        int index = 0;
        Node<T> temp = head;
        while (true)
        {
            if (temp.Next != null)
            {
                temp = temp.Next;
                Debug.Log("index:" + index.ToString() + "   value:" +temp.Data);
                index++;
            }
            else
            {
                break;
            }
        }
    }

   
}
  • 單鏈表測試用例:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class _002_SingleLinkTable : MonoBehaviour {


   
    LinkList<string> sqeList;

    void Start()
    {
         //初始化順序表
        sqeList = new LinkList<string>();

        ////判空操作
        Debug.Log("單鏈表是否為空:" + sqeList.IsEmpty());



        ////新增操作
        Debug.Log("頭插法,新增操作--------------新增'123','456','789'");
        sqeList.Add("123",true);
        sqeList.Add("456",true);
        sqeList.Add("789",true);
        sqeList.Display();
        Debug.Log("尾插法,新增操作--------------新增'123','456','789'");
        sqeList.Add("123");
        sqeList.Add("456");
        sqeList.Add("789");
        sqeList.Display();

        Debug.Log("單鏈表是否為空:" + sqeList.IsEmpty());


        ////插入操作
        Debug.Log("單鏈表插入操作---------------在index=3處插入字串:'111'");
        sqeList.Insert("111", 3);
        sqeList.Display();

        ////刪除操作
        sqeList.Delete(2);
        Debug.Log("單鏈表刪除操作---------------刪除index=2的元素");
        sqeList.Display();

        ////表長
        Debug.Log("單鏈表表長-------------------單鏈表表長:" + sqeList.GetLength());

        ////查詢
        Debug.Log("單鏈表查詢--------------index查value");
        Debug.Log("index=0的值:" + sqeList[0]);
        Debug.Log("index=2的值:" + sqeList.GetElem(2));
        Debug.Log("單鏈表查詢--------------value查index");

        ////定址
        Debug.Log("'789’的index值:" + sqeList.Locate("789"));

        ////清空
        Debug.Log("清空單鏈表");
        sqeList.Clear();
        sqeList.Display();
    }


}

執行結果:
img.jpg


注意:

1.單鏈表在訪問值時,只能從頭節點訪問下去,只能通過前一節點訪問到下一節點,很多時候需要藉助臨時變數來儲存需要的節點。

2.單鏈表的新增可以是尾插方式,也可以是頭插法方式.
採用頭插法,創建出的是一個逆序表,先輸入的在最後。

3.head是表頭指標head.next=null表示該表為空表,表如果不為空,head.next就是首節點,某個節點node.next=null,表示該node為尾節點