C#数据结构及算法之链表

C# 链表

链表是节点的列表,节点包含两部分:值和链接,其中值部分用于储存数据,链接部分用于指向下一个元素的地址,是引用 类型。

单链表

    public class LinkedList
    {
        private class Node
        {
            internal int value;
            internal Node next;
            public Node(int v,Node n)
            {
                value = v;
                next = n;
            }
            public Node(int v)
            {
                value = v;
                next = null;
            }
        }
        private Node head;
        private int count = 0;

        //Size of the List
        public int Size()
        {
            return count;
        }
        //Empty Field
        public bool Empty
        {
            get { return count == 0; }
        }
        ///Insertion methods
        //Insert element at the head
        public void AddHead(int value)
        {
            head = new Node(value, head);
            count++;
        }
        //Insertion of an element at the end 
        public void AddTail(int value)
        {
            var newNode = new Node(value);
            var curr = head;
            if (curr == null)
            {
                head = newNode;
                count++;
                return;
            }
                
            while (curr.next != null)
                curr = curr.next;
            curr.next = newNode;
            count++;
        }

        //Tranversing and print all 
        public void Print()
        {
            var temp = head;
            while (temp != null)
            {
                Console.Write(temp.value + " ");
                temp = temp.next;
            }
        }
        //Sorted Insert
        public void SortedInsert(int value)
        {
            var newNode = new Node(value);
            var curr = head;
            if (curr == null || curr.value > value)
            {
                newNode.next = curr;
                head = newNode;
                return;
            }
            while(curr.next!=null && curr.value < value)
            {
                curr = curr.next;
            }
            newNode.next = curr.next;
            curr.next = newNode;
        }
        //Search Element
        public bool IsPresent(int data)
        {
            var temp = head;
            while (temp != null)
            {
                if (temp.value == data)
                    return true;
                temp = temp.next;
            }
            return false;
        }
        //Delete element 
        public int RemoveHead()
        {
            if (Empty)
                throw new InvalidOperationException("EmptyListException");
            int value = head.value;
            head = head.next;
            count--;
            return value;
        }
        //Delete node from the linked list given its value
        public bool DeleteNode(int delValue)
        {
            var temp = head;
            if (Empty)
                return false;
            if (delValue == head.value)
            {
                head = head.next;
                count--;
                return true;
            }
            while (temp.next != null)
            {
                if (temp.next.value == delValue)
                {
                    temp.next = temp.next.next;
                    count--;
                    return true;
                }
                else
                    temp = temp.next;
            }
            return false;
        }
        //Delete all the occurrence of particular value in the linked list
        public void DeleteNodes(int delValue)
        {
            Node currNode = head;
            Node nextNode;
            if(currNode!=null && currNode.value == delValue)
            {
                head = currNode.next;
                currNode = head;
            }
            while (currNode != null)
            {
                nextNode = currNode.next;
                if(nextNode!=null && nextNode.value == delValue)
                {
                    currNode.next = nextNode.next;
                }
                else
                {
                    currNode = currNode.next;
                }
            }
        }
        //Delete all the elements of a linked list
        public void FreeList()
        {
            head = null;
            count = 0;
        }

        //Reverse a linked list
        public void Reverse()
        {
            Node curr = head;
            Node next=null;
            Node pre=null;
            while (curr != null)
            {
                next = curr.next;
                curr.next = pre;
                pre = curr;
                curr = next;
            }
            head = pre;
        }
        //Recursively reverse a singly linked list
        private Node reverseRecursUtil(Node currentNode,Node nextNode)
        {
            Node ret;
            if (currentNode == null)
                return null;
            if (currentNode.next == null)
            {
                currentNode.next = nextNode;
                return currentNode;
            }
            ret = reverseRecursUtil(currentNode.next, currentNode);
            currentNode.next = nextNode;
         
            return ret;
        }

        public void ReverseRecurse()
        {
            head=reverseRecursUtil(head, null);
        }
        public LinkedList CopyListReversed()
        {
            var ll = new LinkedList();
            Node tempNode = null;
            Node tempNode2 = null;
            Node curr = head;
            while (curr != null)
            {
                tempNode2 = new Node(curr.value, tempNode);
                curr = curr.next;
                tempNode = tempNode2;
            }
            ll.head = tempNode;
            return ll;
        }
        public LinkedList CopyList()
        {
            var ll = new LinkedList();
            Node headNode = null;
            Node tailNode = null;
            Node tempNode = null;
            Node curr = head;
            if (curr == null)
                return null;
            headNode = new Node(curr.value, null);
            tailNode = headNode;//使得headNode的地址与tailNode的地址指向一样
            curr = curr.next;
            while (curr != null)
            {
                tempNode = new Node(curr.value, null);
                tailNode.next = tempNode;
                tailNode = tempNode;
                curr = curr.next;
            }
            ll.head = headNode;
            return ll;
        }
        public bool CompareList(LinkedList ll)
        {
            return compareList(head,ll.head);
        }

        private bool compareList(Node head1,Node head2)
        {
            if (head1 == null && head2 == null)
                return true;
            else if ((head1 == null) || (head2 == null) || (head1.value != head2.value))
                return false;
            else
            {
                return compareList(head1.next, head2.next);
            } 
        }
        public int FindLength()
        {
            Node curr = head;
            int count = 0;
            while (curr!= null)
            {
                curr = curr.next;
                count++;
            }
            return count;
        }
        //Find Node from beginning 
        public int NthFromBegining(int index)
        {
            var size = FindLength();
            if (index > size - 1|| index<0)
                throw new Exception("null element");
            var curr = head;
            var count = 0;
            while(curr!=null && count < index)
            {
                curr = curr.next;
                count++;
            }
            return curr.value;
        }
        public int NthFromEnd(int index)
        {
            int size = FindLength();
            int startIndex;
            if (size != 0 && index > size-1)
                throw new Exception("null element");

            startIndex = size - 1 - index;
            return NthFromBegining(startIndex);
        }  
    }

    class Program
    {
        public static void Main()
        {
            var ll = new LinkedList();
            ll.AddHead(0);
            ll.AddHead(1);
            ll.AddHead(2);
            ll.Print();
            Console.WriteLine();
            ll.ReverseRecurse();
            ll.Print();
        }

Reverse图解

基于递归的reverse实现

posted @ 2022-01-26 00:22  JohnYang819  阅读(155)  评论(0编辑  收藏  举报