单链表相关问题总结

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

namespace Assets.Scripts.Structure
{

    public enum ListFuncType
    {
        Addpend,
        Insert,
        InsertPos,
        RemoveNode,
        RemoveNodeByValue,
        SelectNodeByIndex,
        selectNodeByValue,
        Count
    }
    class node
    {
        public int data;
        public node next;

        public node() { }

        public node(int data) { this.data = data; }
    }
    #region 链表基本操作
    class list
    {
        public node head;

        public int curNodeCount;

        public list() { }

        public list(node head) { this.head = head; }

        public void OutListFunc(ListFuncType type,int data=0,int index=1)
        {
            switch (type)
            {
                case ListFuncType.Addpend:
                    Addpend(data);
                    break;
                case ListFuncType.Insert:
                    Insert(data, index);
                    break;
                case ListFuncType.InsertPos:
                    InsertPos(data, index);
                    break;
                case ListFuncType.RemoveNode:
                    RemoveNode(index);
                    break;
                case ListFuncType.RemoveNodeByValue:
                    RemoveNodeByValue(data);
                    break;
                case ListFuncType.SelectNodeByIndex:
                    Debug.Log(SelectNodeByIndex(index).data);
                    break;
                case ListFuncType.selectNodeByValue:
                    Debug.Log(SelectNodeByValue(data));
                    break;
            }
        }


        void Addpend(int data)
        {
            if (head == null)
            {
                node d = new node(data);
                head = d;
                return;
            }

            node p = head;
            node q = new node(data);

            while (p.next != null)
            {
                p = p.next;
            }
            p.next = q;
        }

        void Insert(int data, int k)
        {
            if (head == null || k < 1) return;

            if (k == 1)
            {
                node d = new node(data);
                d.next = head;
                head = d;
                return;
            }

            node p = head;
            node q = new node();
            node r = new node(data);
            int j = 1;

            while (p.next != null && j < k)
            {
                ++j;
                q = p;
                p = p.next;
            }

            if (k == j)
            {
                q.next = r;
                r.next = p;
                return;
            }
        }

        void InsertPos(int data, int k)
        {
            if (head == null || k < 1) return;

            if (k == 1)
            {
                node d = new node(data);
                d.next = head.next;
                head.next = d;
                return;
            }


            node p = head;
            node q = new node(data);
            int j = 1;
            while (p.next != null && j < k)
            {
                ++j;
                p = p.next;
            }

            if (k == j)
            {
                q.next = p.next;
                p.next = q;
                return;
            }
        }

        node RemoveNode(int k)
        {
            if (head == null || k < 1) return null;

            if (k == 1)
            {
                node tempNode = head;
                head = head.next;
                return tempNode;
            }

            node p = head;
            node q = new node();
            int j = 1;
            node d = new node();
            while (p.next != null && j < k)
            {
                ++j;
                q = p;
                p = p.next;
            }

            if (k == j)
            {
                d = p;
                q.next = p.next;
            }
            return d;
        }

        int RemoveNodeByValue(int data)
        {
            if (head == null) return -1;

            node d = new node(data);

            node p = head;
            node q = new node();
            int j = 1;
            while (p.next != null&&!p.data.Equals(data))
            {
                ++j;
                q = p;
                p = p.next;
            }

            if (j == 1)
            {
                head = head.next;
                return 1;
            }

            q.next = p.next;
            return j;
        }

        node SelectNodeByIndex(int k)
        {
            if (head == null || k < 1) return null;

            node p = head;

            int j = 1;
            while (p.next != null && j < k)
            {
                ++j;
                p = p.next;
            }

            if (k == j)
            {
                return p;
            }

            return null;
        }

        int SelectNodeByValue(int data)
        {
            if (head == null) return -1;

            node p = head;
            int j = 1;
            while (p.next != null && !p.data.Equals(data))
            {
                ++j;
                p = p.next;
            }

            return j;
        }

        public void Print()
        {
            if (head == null) return;

            node p =head;
            while (p.next != null)
            {
                Debug.Log(p.data);
                p = p.next;
            }

            Debug.Log(p.data);
        }

        int CurNodeCount
        {
            get
            {
                if (head == null)
                    return -1;

                node p = head;
                while (p.next != null)
                {
                    ++curNodeCount;
                    p = p.next;
                }
                ++curNodeCount;
                return curNodeCount;
            }
        }
        #endregion

        #region 单链表翻转
        public void ReverList()
        {
            if (head == null) return;

            node p = head.next;
            node q = new node();
            head.next = null;

            while (p != null)
            {
                q = p;
                p = p.next;
                q.next = head;
                head = q;
            }
        }
        //2.
        #endregion

        #region 中点
        public node BackMidNode()
        {
            if (head == null) return null;

            #region 没有限制遍历次数

            int nodeCunt = CurNodeCount;

            int midIndex = 1;
            if (curNodeCount % 2 != 0)
            {
                midIndex = (curNodeCount + 1) / 2;
            }
            else
            {
                midIndex = (curNodeCount - 1) / 2;
            }
            #endregion

            #region 限制遍历次数 遍历一次 节点数为偶数
            node fastNode = head.next.next;
            node lowNode = head.next;
            while (lowNode != null && fastNode != null)
            {
                fastNode = fastNode.next.next;
                lowNode = lowNode.next;
            }
            #endregion

            #region 限制遍历次数 遍历一次 节点数为奇数
            node fastNode1 = head.next.next;
            node lowNode1 = head.next;
            while (lowNode1 != null && fastNode1.next != null)
            {
                fastNode = fastNode.next.next;
                lowNode = lowNode.next;
            }
            #endregion

            return lowNode;
        }
        #endregion

        #region 删除倒数第N个节点
        public node RemoveByPosIndex(int k)
        {
            int index = curNodeCount - k;
            return RemoveNode(index);
        }
        #endregion

        #region 删除重复节点

        public void RemoveRepeatNode()
        {
            if (head == null) return;

            node p = head;

            while (p != null)
            {
                node q = p;

                while (q.next != null)
                {
                    if (q.next.data.Equals(p.data))
                    {
                        q.next = q.next.next;
                    }
                    else
                    {
                        q = q.next;
                    }
                }
                p = p.next;
            }
        }
        #endregion

        #region 环的问题 https://www.cnblogs.com/dancingrain/p/3405197.html
        //1.判断链表是否有环
        bool IsExitLoop()
        {
            node fastNode = head.next.next;
            node slowNode = head.next;
            //快指针跟慢指针相遇,有环
            while (slowNode != null && fastNode.next != null)
            {
                fastNode = fastNode.next.next;
                slowNode = slowNode.next;

                if (fastNode == slowNode)
                {
                    return true;
                }
            }
            return false;
        }

        //2,如果链表存在环,找出环的入口点

        node FindFirstNode()
        {
            node fastNode = head.next.next;
            node slowNode = head.next;

            while (fastNode.next != null && slowNode != null)
            {
                fastNode = fastNode.next.next;
                slowNode = slowNode.next;
                if (fastNode == slowNode) break;
            }

            if (fastNode.next == null || slowNode == null) return null;

            node pre1 = head;
            node pre2 = slowNode;

            while (pre1 != pre2)
            {
                pre1 = pre1.next;
                pre2 = pre2.next;
            }

            return pre1;//环的入口点
        }
        //3.环上的节点数
        int NodeCountLoop()
        {
            node fastNode = head.next.next;
            node slowNode = head.next;
            node tempNode = new node();
            while (slowNode != null && fastNode.next != null)
            {
                fastNode = fastNode.next.next;
                slowNode = slowNode.next;

                if (slowNode == fastNode)
                {
                    tempNode = slowNode;
                    break;
                }
            }

            if (slowNode == null || fastNode.next == null) return -1;
            int j = 1;
            while (slowNode != tempNode)
            {
                ++j;
                slowNode = slowNode.next;
            }

            return j;
        }

        //如果存在环,链表的长度
        int GetNodeCount()
        {
            if (head == null) return -1;

            node fastNode = head.next.next;
            node slowNode = head.next;
            node tempNode = new node();

            int j = 1;

            while (fastNode.next != null && slowNode != null)
            {
                ++j;
                fastNode = fastNode.next.next;
                slowNode = slowNode.next;
                if (fastNode == slowNode)
                {
                    tempNode = slowNode;
                    break;
                }
            }

            if (fastNode.next == null || slowNode == null) return j;

            int h = 1;
            while (slowNode != tempNode)
            {
                ++h;
                slowNode = slowNode.next;
            }


            int L = 1;

            node pre1 = head;
            node pre2 = tempNode;

            while (pre1 != pre2)
            {
                ++L;
                pre1 = pre1.next;
            }

            return h + L;
        }


        #endregion

        #region 合并的问题(无环)

        public node MerageList(node head1,node head2)
        {
            if (head1 == null && head2 == null)
                return null;
            else if (head1 == null)
                return head2;
            else if (head2 == null)
                return head1;

            node newNode = new node();
            node p = head1;
            node q = head2;

            while (p.next != null && q.next != null)
            {
                if (p.data > q.data)
                {
                    newNode.next = q;
                    q = q.next;
                }
                else
                {
                    newNode.next = p;
                    p = p.next;
                }
                newNode = newNode.next;
            }

            while (p.next != null)
            {
                newNode.next = p;
            }

            while (q.next != null)
            {
                newNode.next = q;
            }
            return newNode;
        }

        #endregion

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值