数据结构-单链表&单循环链表

Posted RONGWEIJUN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构-单链表&单循环链表相关的知识,希望对你有一定的参考价值。

第一次听到链表这个词的时候觉得很酷,可能玩游戏觉得链是武器,固定思维了,哈哈。

 

 

 

接口:

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

 其实大致实现差不多。

以上是关于数据结构-单链表&单循环链表的主要内容,如果未能解决你的问题,请参考以下文章

数据结构链表,看这两篇就足够了(上集,动图版)

数据结构单链表&&静态链表详解和代码实例

循环链表(循环单链表循环双链表)的相关操作的代码实现(C语言)

数据结构自学笔记——线性表

数据结构循环链表&&双向链表详解和代码实例

数据结构C语言版 —— 链表增删改查实现(单链表+循环双向链表)