C# 鏈表反轉

鏈表反轉分這麼兩種情況,

一種是鏈表頭節點始終前置,那這時候需要傳一個頭節點特有的標記;(簡稱:頭不轉)

HEAD->Test1->Test2->Test3->Test4

反轉後:

HEAD->Test4->Test3->Test2->Test1


 

另一種是不管頭節點,連同頭節點一起反轉。 (簡稱:頭也轉)

HEAD->Test1->Test2->Test3->Test4

反轉後:

Test4->Test3->Test2->Test1->HEAD


不管轉不轉頭,都有遞歸實現和非遞歸實現。

先看一下我的鏈表類。

    public class LinkNode<T>
    {
       public T Data { get; set; }
      // public LinkNode<T> prev { get; set; }
        public LinkNode<T> Next { get; set; }

        public LinkNode(T data)
        {
            this.Data = data;
            Next = null;
        }
        public LinkNode()
        {
            this.Next=null;
        }

    }
    public class LinkList<T>
    {
        public LinkNode<T> Head;
        public LinkList()
        {
            Head = new LinkNode<T>();
        }
        public void AddLinkNode(T valueToAdd)
        {
            var newNode = new LinkNode<T>(valueToAdd);
            LinkNode<T> tmp = Head;
            while (tmp.Next != null)
            {
                tmp = tmp.Next;
            }
            tmp.Next = newNode;


        }
        public void PrintAllNodes()
        {
            LinkNode<T> tmp = Head;
            while (tmp != null)
            {
                Console.WriteLine(tmp.Data);
                tmp = tmp.Next;
            }
        }
    }

好了,然後看一下

①頭也轉情況的遞歸實現:

        /// <summary>
        /// 頭也轉的遞歸實現
        /// </summary>
        /// <param name="node1"></param>
        /// <param name="node2"></param>
        /// <returns></returns>
        public LinkNode<T> ReverseRecursiveNohead(LinkNode<T> node1, LinkNode<T> node2)
        {
            bool head = false;
            if (node1 == this.Head) head = true;
            LinkNode<T> tmp = node2.Next;
            node2.Next = node1;
            if (head) node1.Next = null;
            if (tmp == null) {
                return node2; }
            else
            {
               return ReverseRecursiveNohead(node2, tmp);
            }
        }

main中調用

            var linklist = new LinkList<string>();
            Console.WriteLine("______原始鏈表打印________");
            linklist.Head.Data = "HEAD";
            linklist.AddLinkNode("test1");
            linklist.AddLinkNode("test2");
            linklist.AddLinkNode("test3");
            linklist.AddLinkNode("test4");
            linklist.PrintAllNodes();
            Console.WriteLine("______頭也轉的遞歸實現________");
            
            linklist.Head= linklist.ReverseRecursiveNohead(linklist.Head, linklist.Head.Next);
            linklist.PrintAllNodes();

 

效果:

②頭也轉情況的非遞歸實現:

/// <summary>
        /// 頭也轉的非遞歸實現
        /// </summary>
        /// <param name="head"></param>
        /// <returns></returns>
        public LinkNode<T> ReverseNonRecursive(LinkNode<T> head)
        {
            LinkNode<T> tmp1 = new LinkNode<T>(), tmp2 = new LinkNode<T>();
            while (head != null)
            {
                tmp2 = head.Next;//save next head
                head.Next = tmp1;
                tmp1 = head;
                head = tmp2;

            }
            return tmp1;

        }

main中調用

            var linklist = new LinkList<string>();
            Console.WriteLine("______原始鏈表打印________");
            linklist.Head.Data = "HEAD";
            linklist.AddLinkNode("test1");
            linklist.AddLinkNode("test2");
            linklist.AddLinkNode("test3");
            linklist.AddLinkNode("test4");
            linklist.PrintAllNodes();
            Console.WriteLine("_______頭也轉的非遞歸實現_______");
            linklist.Head = linklist.ReverseNonRecursive(linklist.Head);
            linklist.PrintAllNodes();

效果:

 

③頭不轉的遞歸實現:

/// <summary>
        /// 頭結點不轉,頭始終是頭的遞歸實現
        /// </summary>
        /// <param name="node1"></param>
        /// <param name="node2"></param>
        /// <param name="head"></param>
        /// <returns></returns>
        public LinkNode<T> ReverseRecurse(LinkNode<T> node1,LinkNode<T> node2,T head){
            if (node2 == null)
            {
                return null;
            }
            else
            {
                if (node2.Next == null)
                {
                    Head.Next = node2;
                    node2.Next = node1;
                    node1.Next = null;
                    return Head;
                }
                else
                {
                    ReverseRecurse(node2, node2.Next,head);
                    node2.Next = node1;
                    if (node2.Next.Data.Equals(head))
                    {
                        node2.Next = null;
                        return Head; 
                    }
                    node1.Next = null;
                    return Head;
                }
            }

        }

main中調用

            var linklist = new LinkList<string>();
            Console.WriteLine("______原始鏈表打印________");
            linklist.Head.Data = "HEAD";
            linklist.AddLinkNode("test1");
            linklist.AddLinkNode("test2");
            linklist.AddLinkNode("test3");
            linklist.AddLinkNode("test4");
            linklist.PrintAllNodes();

            Console.WriteLine("_______頭不轉的遞歸實現_______");
            linklist.ReverseRecurse(linklist.Head,linklist.Head.Next,"HEAD");
            linklist.PrintAllNodes();

效果:

 好像還差一種,大家自己發揮~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章