C # way linked list implementation ---- constructed in understanding the data structure of object-oriented thinking

  1. Why use singly linked list?     

      First, remove the check list is very handy if you are programming, the need to remove the high operating frequency of the data, then, as a one-way linked list data structure is a good choice. The list only needs to delete the delete operation to delete data position, the elements do not need a position behind eleven shift, thereby greatly enhancing the efficiency of the deletion operation; same insertion operation, since the non-sequential non-contiguous storage structure list in when inserting the complexity is O (1), only modified to create a node pointer at the position relation, and the complexity of the structure of the array in O (n), while, if the capacity of the array reaches a time limit, triggers expansion of operations.

      However, although the list and delete operations more efficient than digital insertion structure, but the larger the index on a linked list data structure than the overhead array, the former is O (logn) complexity, which is only O (1 ). When we designed the program, we need to follow their own needs to create, in the world there is no perfect thing.

      2. The one-way linked list code implements (C #)

analysis

                                 

Unlike the list stored in the form of an array, consecutive memory addresses, the memory address of each element in the list may be dispersed. The disorder, which requires additional data in each variable to store a pointer to its next data address: next, for each element in the list.

We call this data and next data structure is composed of a "node" is a node that has two basic fields.

Here begin construction properties and behavior of the list.

He has a list header Head, showing their attributes such as the length of the Length information;

List of behavior index elements, add elements to the end, any position insert elements, remove elements on the specified location, get the elements of a location, such as computing elements in the position table.

// 这是链表中,单个数据节点的父类,T 是用来确定数据类型的参数,类的固定书写格式
public class LoopLinkNode<T> where T : object
{
    private T data;// 节点的数据域,
    private LoopLinkNode<T> next; // 该节点的下一个节点(指针域)

    public T Data 
    {
        set { data = value; }
        get { return data; }
    }
    public LoopLinkNode<T> Next
    {
        set { next = value; }
        get { return next; }
    }

    // 构造函数,节点的创建
    public LoopLinkNode(T data)
    {
        this.data = data;
        next = null;
    }
}
    // 这是链表的父类,链表的属性、字段、行为都在这里定义
    public class LoopLink<T> where T : object
    {
        // 链表的构造函数,在 new 的时候调用,这里创建了一个空的链表,head 节点为空
        public LoopLink()
        {
            this.head = null;            
        }

        // 链表的头信息属性
        private LoopLinkNode<T> head;
        public LoopLinkNode<T> Head
        {
            set
            {
                head = value;
                head.Next = head;
            }
            get { return head; }
        }

        // 链表的长度属性
        public int Length { get { return GetLength(); } }

        /// <summary>
        /// 索引器
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public LoopLinkNode<T> this[int index]
        {
            set
            {
                if (IsEmpty())
                    throw new Exception("链表为空");
                if (index < 0 || index > this.Length - 1)
                    throw new Exception("索引超出链表长度");
                LoopLinkNode<T> node = head;
                for (int i = 0; i < index; i++)
                {
                    node = node.Next;                    
                }
                node.Data = value.Data;
                node.Next = value.Next;
            }
            get
            {
                if (IsEmpty())
                    throw new Exception("链表为空");
                if (index < 0 || index > this.Length - 1)
                    throw new Exception("索引超出链表长度");
                LoopLinkNode<T> node = head;
                for (int i = 0; i < index; i++)
                {
                    node = node.Next;                    
                }
                return node;
            }
        }

        /// <summary>
        /// 获取链表长度
        /// </summary>
        /// <returns></returns>
        public int GetLength()
        {
            if (IsEmpty())
                return 0;
            int length = 1;
            LoopLinkNode<T> temp = head;
            while (temp.Next != head)
            {
                temp = temp.Next;
                length++;
            }
            return length;
        }

        /// <summary>
        /// 清空链表所有元素,只需要将 头信息置空即可
        /// </summary>
        public void Clear()
        {
            this.head = null;
        }

        /// <summary>
        /// 检查链表是否为空
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty()
        {
            if (head == null)
                return true;
            return false;
        }

        /// <summary>
        /// 检查链表是否已满
        /// </summary>
        /// <returns></returns>
        public bool IsFull()
        {
            return false;
        }

        /// <summary>
        /// 在链表的最末端添加一个新项
        /// </summary>
        /// <param name="item"></param>
        public void Append(T item)
        {
            if (IsEmpty())
            {
                this.Head = new LoopLinkNode<T>(item);
                return;
            }
            LoopLinkNode<T> node = new LoopLinkNode<T>(item);
            LoopLinkNode<T> temp = head;
            while (temp.Next != head)
            {
                temp = temp.Next;
            }
            temp.Next = node;
            node.Next = head;
        }

        /// <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.Length)
                throw new Exception("给定索引超出链表长度");
            LoopLinkNode<T> temp = new LoopLinkNode<T>(item);
            LoopLinkNode<T> node = head;
            if (index == 0)
            {
                while (node.Next != head)
                {
                    node = node.Next;
                }
                node.Next = temp;
                temp.Next = this.head;
                return;
            }
            for (int i = 0; i < index - 1; i++)
            {
                node = node.Next;
            }
            LoopLinkNode<T> temp2 = node.Next;
            node.Next = temp;
            temp.Next = temp2;
        }

        /// <summary>
        /// 删除链表指定位置的项目
        /// </summary>
        /// <param name="index"></param>
        public void Delete(int index)
        {
            if (IsEmpty())
                throw new Exception("链表为空,没有可清除的项");
            if (index < 0 || index > this.Length - 1)
                throw new Exception("给定索引超出链表长度");
            LoopLinkNode<T> node = head;
            if (index == 0)
            {
                while (node.Next != head)
                {
                    node = node.Next;
                }
                this.head = head.Next;
                node.Next = this.head;
                return;
            }
            for (int i = 0; i < index - 1; i++)
            {
                node = node.Next;
            }
            node.Next = node.Next.Next;
        }

        /// <summary>
        /// 获取链表指定位置的元素的值
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T GetItem(int index)
        {
            if (index < 0 || index > this.Length - 1)
                throw new Exception("索引超出链表长度");
            LoopLinkNode<T> node = head;
            for (int i = 0; i < index; i++)
            {
                node = node.Next;
            }
            return node.Data;
        }

        /// <summary>
        /// 根据给定的值查找链表中哪个元素为这个值,如果链表中存在两个元素值相同,则取排在链表前面的元素
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public int Locate(T value)
        {
            if (IsEmpty())
                throw new Exception("链表为空");
            LoopLinkNode<T> node = head;
            int index = 0;
            while (node.Next != head)
            {
                if (node.Data.Equals(value))
                    return index;
                else
                    index++;
                node = node.Next;
            }
            if (node.Data.Equals(value))
                return index;
            else
                return -1;
        }
}

Test code:

    private void Start()
    {
        LoopLink<Vector2> linkList = new LoopLink<Vector2>();
        for (int i = 0; i < 10; i++)
        {
            linkList.Append(new Vector2(i, i % 2));
        }
        Debug.Log("原始数据:");
        for (int i = 0; i < linkList.Length; i++)
        {
            Debug.Log(linkList[i].Data);
        }
        Debug.Log("在倒数第二个的位置处插入元素 (999, 999) 后:");
        linkList.Insert(new Vector2(999, 999), linkList.Length - 2);
        for (int i = 0; i < linkList.Length; i++)
        {
            Debug.Log(linkList[i].Data);
        }
        linkList.Delete(linkList.Length - 1);
        Debug.Log("删除最后一个元素:");
        for (int i = 0; i < linkList.Length; i++)
        {
            Debug.Log(linkList[i].Data);
        }
        Debug.Log("取出第2个元素是: " + linkList.GetItem(1));
        Debug.Log("(0,0)元素在链表中的索引是:" + linkList.Locate(Vector2.zero));
    }

Test Results:

                                                        

 

Released five original articles · won praise 1 · views 270

Guess you like

Origin blog.csdn.net/THUNDERDREAMER_OR/article/details/104300039