數據結構-單鏈表&單循環鏈表


第一次聽到鏈表這個詞的時候覺得很酷,可能玩游戲覺得鏈是武器,固定思維了,哈哈。

 

 

 

接口:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _001_線性表
{
    interface IListDS<T>
    {
        int GetLength();
        void Clear();
        bool IsEmpty();
        void Add(T item);
        void Insert(T item, int index);
        T Delete(int index);
        T this[int index] { get; }
        T GetEle(int index);
        int Locate(T value);

    }
}
View Code

單向節點:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _001_線性表
{   

    /// <summary>
    /// 單鏈表節點
    /// </summary>
    /// <typeparam name="T"></typeparam>
    class Node<T>
    {
        private T data;//存儲數據
        private Node<T> next;//指針 用來指向下一個元素
        public Node(T value)
        {
            data = value;
            next = null;
        }
        public Node(T value,Node<T> next)
        {
            this.data = value;
            this.next = next;
        }
        public Node(Node<T> next)
        {
            this.next = next;
        }
        public Node()
        {
            this.data = default(T);
            this.next = null;
        }
        public T Data
        {
            get { return data; }
            set { data = value; }
        }
        public Node<T> Next
        {
            get
            {
                return next;
            }
            set
            {
                next = value;
            }
        }
    }
}
View Code

單向鏈表:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _001_線性表
{
    /// <summary>
    /// 單鏈表
    /// </summary>
    /// <typeparam name="T"></typeparam>
    class LinkList<T> : IListDS<T>
    {
        private Node<T> head;//存儲一個頭結點
        public LinkList()
        {
            head = null;
        }

        public T this[int index] => GetEle(index);

        /// <summary>
        /// 添加節點 
        /// </summary>
        /// <param name="item"></param>
        public void Add(T item)
        {
            Node<T> newNode = new Node<T>(item);//根據新的數據創建一個新的節點
            //如果頭結點為空,那么這個新的節點就是頭節點
            if (IsEmpty())
            {
                head = newNode;
                return;
            }
            else
            {
                //把新來的結點放到 鏈表的尾部
                //要訪問到鏈表的尾部結點
                Node<T> temp = head;
                while (temp.Next != null)
                {
                  temp = temp.Next;
                }
                temp.Next = newNode;
            }

        }

        /// <summary>
        /// 清空
        /// </summary>
        public void Clear()
        {
            head = null;
        }

        /// <summary>
        /// 刪除節點
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T Delete(int index)
        {
            T data = default(T);
            if (index == 0) //刪除頭節點
            {               
                data = head.Data;
                head = head.Next;
            }
            else
            {
                Node<T> pre = head;
                for (int i = 1; i < index-1; i++)               
                {
                    //讓pre向后移動一個位置
                    pre = pre.Next;
                }
                Node<T> Del = pre.Next; //得到要刪除的節點
                data = Del.Data;   //得到刪除節點的數據
                Node<T> atf = Del.Next; // 得到刪除節點的之后的節點
                pre.Next = atf; //連接 前后節點
            }
            return data;
        }

        /// <summary>
        /// 獲取指定位置元素
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T GetEle(int index)
        {
            Node<T> temp = head;
            for (int i = 0; i < index; i++)
            {
                temp = temp.Next;
            }
            return temp.Data;
        }
        /// <summary>
        /// 獲取長度
        /// </summary>
        /// <returns></returns>
        public int GetLength()
        {
            if (IsEmpty())
            {
                return 0;
            }
            Node<T> temp = head;
            int count = 1;
            while (temp.Next != null)
            {
                    count++;
                    temp = temp.Next;
            }
            return count;
        }
        /// <summary>
        /// 插入節點
        /// </summary>
        /// <param name="item"></param>
        /// <param name="index"></param>
        public void Insert(T item, int index)
        {
            Node<T> newNode = new Node<T>(item); //新節點
            if (index == 0)//插入到頭節點
            {
                newNode.Next = head;
                head = newNode;
            }
            else
            {
                Node<T> pre = head;
                for (int i = 1; i <=index-1; i++)
                {
                    //讓temp向后移動一個位置
                    pre = pre.Next;
                }
                Node<T> preNode = pre; //要插入的 前面節點
                Node<T> afterNode = pre.Next; //要插入的 后面節點
                preNode.Next = newNode; //前節點的尾巴 連接 新節點
                newNode.Next = afterNode; //新節點的尾巴 連接 后面的節點
            }
        }

        /// <summary>
        /// 是否為空
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty()
        {
            return head == null;
        }

        public int Locate(T value)
        {
            Node<T> temp = head;
            if (IsEmpty())
            {
                return -1;
            }
            else
            {
                int index = 0;
                while (true)
                {
                    if (temp.Data.Equals(value)) //相同就直接返回
                    {
                        return index;
                    }
                    else
                    {
                        if (temp.Next != null) //下個節點不為空
                        {
                            index++;
                            temp = temp.Next;
                        }
                        else //為空
                        {
                            break;
                        }
                    }
                }
                return -1;
            }
         
        }
    }
}
View Code

 

單向循環鏈表

 

 

區別看圖↑

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _001_線性表
{
    /// <summary>
    /// 單鏈循環鏈表
    /// </summary>
    /// <typeparam name="T"></typeparam>
    class LoopLinkList<T> : IListDS<T>
    {
        private Node<T> head;
        public Node<T> Head
        {
            set
            {
                head = value;
                head.Next = head;
            }
            get { return head; }
        }

        public T this[int index] => GetEle(index);

        /*
public Node<T> this[int index]
{
set
{

if (IsEmpty())
throw new Exception("鏈表為空");
if (index < 0 || index > this.GetLength() - 1)
throw new Exception("索引超出鏈表長度");
Node<T> node = head;
for (int i = 0; i < index; i++)
{
node = node.Next;
}
node.Data = value.Data;
node.Next = value.Next;
}
get
{
if (index < 0 || index > this.GetLength() - 1)
throw new Exception("索引超出鏈表長度");
Node<T> node = head;
for (int i = 0; i < index; i++)
{
node = node.Next;
}
return node;
}
}
*/



        /// <summary>
        /// 在末端添加一個新節點
        /// </summary>
        /// <param name="item"></param>
        public void Add(T item)
        {
            Node<T> newNode = new Node<T>(item);
            if (IsEmpty()) //判斷是否為空,物是人非
            {
                this.Head = newNode;
                return;
            }
            else
            {
                Node<T> temp = head;
                while (temp.Next != head) //循環 判斷是否為頭部,是就跳出循環
                {
                     temp = temp.Next;
                }
                temp.Next = newNode;
                newNode.Next = head;
            }

        }

        /// <summary>
        /// 清空表元素
        /// </summary>
        public void Clear()
        {
            head = null;
        }

        /// <summary>
        /// 刪除鏈表指定位置的元素
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T Delete(int index)
        {
            T data = default(T);
            if (IsEmpty())
                throw new Exception("鏈表為空,沒有可清除的項");
            if (index < 0 || index > this.GetLength() - 1)
                throw new Exception("給定索引超出鏈表長度");

            Node<T> preNode = head;
            if (index == 0)
            {
                while (preNode.Next!=head)
                {
                    preNode = preNode.Next;
                }
                this.head = head.Next;
                 data=preNode.Next.Data;
                preNode.Next = this.head;
            }
            else
            {
                for (int i = 1; i < index-1; i++)
                {
                    preNode = preNode.Next;
                }
                preNode.Next = preNode.Next.Next;
            }
            return data;
        }

        public T GetEle(int index)
        {
            if (index < 0 || index > this.GetLength() - 1)
                throw new Exception("索引超出鏈表長度");
            Node<T> node = head;
            for (int i = 0; i < index; i++)
            {
                node = node.Next;
            }
            return node.Data;
        }

        /// <summary>  
        /// 獲取鏈表長度  
        /// </summary>  
        /// <returns></returns>  
        public int GetLength()
        {
            if (IsEmpty())
            {
                return 0;
            }
            else
            {
                int length = 1;
                Node<T> temp = head;
                while (temp.Next!=head)
                {
                    temp = temp.Next;
                    length++;
                }
                return length;
            }
        }

        /// <summary>
        /// 在鏈表指定的位置插入一個新節點
        /// </summary>
        /// <param name="item"></param>
        /// <param name="index"></param>
        public void Insert(T item, int index)
        {
            if (IsEmpty())
                throw new Exception("數據鏈表為空");
            if (index < 0 || index > this.GetLength())
                throw new Exception("給定索引超出鏈表長度");

            Node<T> newNode = new Node<T>(item);
            Node<T> preNode = head;
            if (index == 0) //等於零  先找到 鏈表中 head的前一個節點 這個節點連接 head
            {
                while (preNode.Next!=head)
                {
                    preNode = preNode.Next;
                }
                preNode.Next = newNode;
                newNode.Next = this.head;
                return;
            }
            else
            {
                for (int i = 1; i < index-1; i++)
                {
                    preNode = preNode.Next;
                }
                Node<T> atfNode= preNode.Next;
                preNode.Next = newNode;
                newNode.Next = atfNode;
            }

        }

        /// <summary>
        /// 清空是否為空
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty()
        {
            return head == null;
        }

        /// <summary>  
        /// 根據給定的值查找鏈表中哪個元素為這個值,如果鏈表中存在兩個元素值相同,則取排在鏈表前面的元素  
        /// </summary>  
        /// <param name="value"></param>  
        /// <returns></returns>  
        public int Locate(T value)
        {
            if (IsEmpty())
                throw new Exception("鏈表為空");
            Node<T> preNode = head;
            int index = 0;
            while (true)
            {
                if (!preNode.Data.Equals(value))
                {
                    if (preNode.Next != head)
                    {
                        index++;
                        preNode = preNode.Next;
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    return index;
                }
            }
            return -1;
        }
    }
}
View Code

 其實大致實現差不多。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM