コード例 #1
0
        public bool IsSameDataList(SinglyLinkedList <T> otherList)
        {
            SllNode <T> currentForThisList  = this.Head;
            SllNode <T> currentForOtherList = otherList.Head;

            while (currentForThisList != null && currentForOtherList != null)
            {
                if (currentForThisList.Data.CompareTo(currentForOtherList.Data) == 0)
                {
                    currentForThisList  = currentForThisList.Next;
                    currentForOtherList = currentForOtherList.Next;
                }
                else
                {
                    return(false);
                }
            }

            if (currentForThisList == null && currentForOtherList == null)
            {
                return(true);
            }

            return(false);
        }
コード例 #2
0
 public void DeleteNodeTricky(SllNode <T> node)
 {
     if (node.Next != null)
     {
         //Trick works only if its not last node
         SllNode <T> nextNode = node.Next;
         if (nextNode != null)
         {
             node.Data     = nextNode.Data;
             node.Next     = nextNode.Next;
             nextNode.Next = null;//Garbage collector will delete it
         }
     }
     else if (node == this.Head)
     {
         this.Head = null;
     }
     else
     {
         SllNode <T> current = this.Head;
         while (current.Next != node)
         {
             current = current.Next;
         }
         current.Next = node.Next; //always null
     }
 }
コード例 #3
0
        public bool IsPalindromeWithStack()
        {
            Stack <SllNode <T> > stack       = new Stack <SllNode <T> >();
            SllNode <T>          currentNode = Head;

            while (currentNode != null)
            {
                stack.Push(currentNode);
                currentNode = currentNode.Next;
            }

            //Now check by poping each node from stack and compare with current iteration
            SllNode <T> otherIterationNode = Head;

            while (otherIterationNode != null)
            {
                SllNode <T> stackNode = stack.Pop();
                if (stackNode.Data.CompareTo(otherIterationNode.Data) != 0)
                {
                    return(false);
                }
                otherIterationNode = otherIterationNode.Next;
            }

            return(true);
        }
コード例 #4
0
        private void DeleteNodesAtDistanceRecursiveInternalUtil(SllNode <T> currentHead, int distance)
        {
            if (currentHead == null)
            {
                return;
            }

            SllNode <T> prev = null;

            //Skip distance nodes
            for (int i = 1; i < distance; i++)
            {
                prev = currentHead;
                if (currentHead == null)
                {
                    return;
                }
                currentHead = currentHead.Next;
            }

            if (currentHead != null && prev != null)
            {
                prev.Next   = currentHead.Next;
                currentHead = currentHead.Next;
            }
            DeleteNodesAtDistanceRecursiveInternalUtil(currentHead, distance);
        }
コード例 #5
0
        private SllNode <T> MergeSortedHalfs(SllNode <T> firstHalf, SllNode <T> secondHalf)
        {
            if (firstHalf == null)
            {
                return(secondHalf);
            }
            if (secondHalf == null)
            {
                return(firstHalf);
            }

            SllNode <T> combinedList = null;

            if (firstHalf.Data.CompareTo(secondHalf.Data) <= 0)
            {
                combinedList      = firstHalf;
                combinedList.Next = MergeSortedHalfs(firstHalf.Next, secondHalf);
            }
            else
            {
                combinedList      = secondHalf;
                combinedList.Next = MergeSortedHalfs(firstHalf, secondHalf.Next);
            }
            return(combinedList);
        }
コード例 #6
0
        private void SwapData(SllNode <T> outer, SllNode <T> inner)
        {
            T tempData = outer.Data;

            outer.Data = inner.Data;
            inner.Data = tempData;
        }
コード例 #7
0
        public SllNode <T> GetNthNodeFromEnd(int index)
        {
            SllNode <T> currentAhead  = Head;
            SllNode <T> currentBehind = Head;
            int         i             = 0;

            //Skip index nodes from beginning
            for (i = 0; currentAhead != null && i < index; i++)
            {
                currentAhead = currentAhead.Next;
            }

            if (i < index)
            {
                return(null);
            }

            //when ahead one reaches end of list, behind one whould be index behind from end
            while (currentAhead != null)
            {
                currentAhead  = currentAhead.Next;
                currentBehind = currentBehind.Next;
            }

            return(currentBehind); // not found, index > length of sll
        }
コード例 #8
0
        public bool areIdenticalRecursive(SinglyLinkedList <T> otherList)
        {
            SllNode <T> currentOfThisList  = this.Head;
            SllNode <T> currentOfOtherList = otherList.Head;

            return(areIdenticalRecursive(currentOfThisList, currentOfOtherList));
        }
コード例 #9
0
        public bool IsPalindromeRecursive()
        {
            SllNode <T> currentReverse = Head;
            SllNode <T> currentForward = Head;

            //Critical - passing by reference will work as data member/double pointer
            return(IsPalindromeRecursiveInternalUtil(currentReverse, ref currentForward));
        }
コード例 #10
0
        public void PushToHead(SllNode <T> newNode)
        {
            //Append whole list behind new node
            newNode.Next = Head;

            //Make new node as head of the list
            Head = newNode;
        }
コード例 #11
0
 public void ReverseRecursive()
 {
     if (Head != null)
     {
         SllNode <T> oldHead = Head;
         ReverseRecursiveInternalUtil(Head);
         oldHead.Next = null; //Critical to make new last node's next as null
     }
 }
コード例 #12
0
        public void PushToHead(T data)
        {
            //Allocate new node
            SllNode <T> newNode = new SllNode <T>(data);

            //Append whole list behind new node
            newNode.Next = Head;

            //Make new node as head of the list
            Head = newNode;
        }
コード例 #13
0
        public void Print()
        {
            SllNode <T> current = Head;

            while (current != null)
            {
                Console.Write(current.Data);
                Console.Write("->");
                current = current.Next;
            }
            Console.WriteLine();
        }
コード例 #14
0
 public bool areIdenticalRecursive(SllNode <T> currentOfThisList, SllNode <T> currentOfOtherList)
 {
     if (currentOfThisList == null && currentOfOtherList == null)
     {
         return(true);
     }
     if (currentOfThisList.Data.CompareTo(currentOfOtherList.Data) != 0)
     {
         return(false);
     }
     return(areIdenticalRecursive(currentOfThisList.Next, currentOfOtherList.Next));
 }
コード例 #15
0
        public int GetCount()
        {
            SllNode <T> current = Head;
            int         count   = 0;

            while (current != null)
            {
                count++;
                current = current.Next;
            }
            return(count);
        }
コード例 #16
0
        public void ReverseList()
        {
            SllNode <T> current = Head, prev = null, next = null;

            while (current != null)
            {
                next         = current.Next;
                current.Next = prev;
                prev         = current;
                current      = next;
            }
            Head = prev;
        }
コード例 #17
0
        private void SplitListIntoTwoHalf(SllNode <T> currentHead, ref SllNode <T> firstHalf, ref SllNode <T> secondHalf)
        {
            SllNode <T> prevToMiddleNode = null;
            SllNode <T> middleNode       = this.GetMiddleNode(currentHead, out prevToMiddleNode);

            prevToMiddleNode = middleNode;
            middleNode       = middleNode.Next;

            prevToMiddleNode.Next = null;

            firstHalf  = currentHead;
            secondHalf = middleNode;
        }
コード例 #18
0
        private void ReverseRecursiveInternalUtil(SllNode <T> currentNode)
        {
            SllNode <T> nextNode = currentNode.Next;

            if (nextNode != null)
            {
                ReverseRecursiveInternalUtil(currentNode.Next);
                nextNode.Next = currentNode;
            }
            else
            {
                Head = currentNode;
            }
        }
コード例 #19
0
        public bool areIdentical(SinglyLinkedList <T> otherList)
        {
            SllNode <T> currentOfThisList  = this.Head;
            SllNode <T> currentOfOtherList = otherList.Head;

            while (currentOfThisList != null && currentOfOtherList != null)
            {
                if (currentOfThisList.Data.CompareTo(currentOfOtherList.Data) != 0)
                {
                    return(false);
                }
                currentOfThisList  = currentOfThisList.Next;
                currentOfOtherList = currentOfOtherList.Next;
            }
            return(currentOfThisList == null && currentOfOtherList == null);
        }
コード例 #20
0
        public int countOccurances(T data)
        {
            int         count   = 0;
            SllNode <T> current = Head;

            while (current != null)
            {
                if (current.Data.CompareTo(data) == 0)
                {
                    count++;
                }

                current = current.Next;
            }
            return(count);
        }
コード例 #21
0
        private SllNode <T> GetMiddleNode(SllNode <T> startOfList, out SllNode <T> prevToMiddleNode)
        {
            SllNode <T> fastPointer = startOfList;
            SllNode <T> slowPointer = startOfList;

            prevToMiddleNode = null;

            while (fastPointer != null && fastPointer.Next != null && fastPointer.Next.Next != null)
            {
                fastPointer      = fastPointer.Next.Next;
                prevToMiddleNode = slowPointer;
                slowPointer      = slowPointer.Next;
            }

            return(slowPointer);
        }
コード例 #22
0
        public SllNode <T> GetNthNodeFromStart(int index)
        {
            SllNode <T> current = Head;
            int         count   = 0;

            while (current != null && current.Next != null)
            {
                count++;
                if (count == index)
                {
                    return(current);
                }

                current = current.Next;
            }
            return(null); // not found, index > length of sll
        }
コード例 #23
0
        public bool IsLoopPresent()
        {
            SllNode <T> fastPointer = Head;
            SllNode <T> slowPointer = Head;

            while (fastPointer != null && fastPointer.Next != null)
            {
                fastPointer = fastPointer.Next.Next;
                slowPointer = slowPointer.Next;
                if (fastPointer == slowPointer)
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #24
0
        public bool IsLoopPresentByUsingExtraSpace()
        {
            Dictionary <SllNode <T>, bool> hashTable = new Dictionary <SllNode <T>, bool>();
            SllNode <T> currentNode = Head;

            while (currentNode != null)
            {
                if (hashTable.ContainsKey(currentNode))
                {
                    return(true);//Loop detected
                }

                hashTable.Add(currentNode, true);
                currentNode = currentNode.Next;
            }
            return(false);
        }
コード例 #25
0
        private bool IsPalindromeRecursiveInternalUtil(SllNode <T> currentReverse, ref SllNode <T> currentForward)
        {
            bool remainingListIsPalindrome = true;

            //Go ahead till you reach end of list for one pointer
            if (currentReverse.Next != null)
            {
                remainingListIsPalindrome = IsPalindromeRecursiveInternalUtil(currentReverse.Next, ref currentForward);
            }

            //Now when coming back from recursion, will check for data equality
            if (currentForward.Data.CompareTo(currentReverse.Data) == 0)
            {
                currentForward = currentForward.Next;
                return(remainingListIsPalindrome);
            }
            return(false);
        }
コード例 #26
0
        public bool IsPalindromeWithoutExtraSpace()
        {
            SllNode <T> prevToMiddleNode = null;
            SllNode <T> middleNode       = this.GetMiddleNode(out prevToMiddleNode);
            SllNode <T> backUpMiddleNode = middleNode;

            //Get the starting of list after middle node
            SllNode <T> nextToMiddleNode = middleNode.Next;

            //Get the odd or even count
            int length = GetCount();

            //Critical to ignore middle node if its odd count
            if (length % 2 != 0)
            {
                middleNode = prevToMiddleNode;
            }

            // Break list from middle
            middleNode.Next = null;

            //Make new second half from next to middle
            SinglyLinkedList <T> newSecondHalfList = new SinglyLinkedList <T>(nextToMiddleNode);

            //Reverse second half
            newSecondHalfList.ReverseList();

            //Compare original first half and reversed second half
            bool isSame = this.IsSameDataList(newSecondHalfList);

            //Reverse second half again to make original list
            newSecondHalfList.ReverseList();

            if (length % 2 != 0)
            {
                middleNode.Next = backUpMiddleNode;
                middleNode      = middleNode.Next;
            }

            //Join both list again
            middleNode.Next = newSecondHalfList.Head;

            return(isSame);
        }
コード例 #27
0
        public void SortByDataMovement()
        {
            SllNode <T> outer = Head;

            while (outer != null)
            {
                SllNode <T> inner = outer;
                while (inner != null)
                {
                    if (outer.Data.CompareTo(inner.Data) > 0)
                    {
                        //We are swaping data itself and not nodes
                        SwapData(outer, inner);
                    }
                    inner = inner.Next;
                }
                outer = outer.Next;
            }
        }
コード例 #28
0
        private SllNode <T> MergeSortInternalUtil(SllNode <T> currentHead)
        {
            //If no node or only one node then it is already sorted, no more recursion
            if (currentHead == null || currentHead.Next == null)
            {
                return(currentHead);
            }

            SllNode <T> firstHalf  = null;
            SllNode <T> secondHalf = null;

            SplitListIntoTwoHalf(currentHead, ref firstHalf, ref secondHalf);

            SllNode <T> firstHalfNewHead  = MergeSortInternalUtil(firstHalf);
            SllNode <T> secondHalfNewHead = MergeSortInternalUtil(secondHalf);

            SllNode <T> newHead = MergeSortedHalfs(firstHalfNewHead, secondHalfNewHead);

            return(newHead);
        }
コード例 #29
0
        public SllNode <T> DeleteNode(SllNode <T> node)
        {
            if (this.Head == node)
            {
                SllNode <T> nextNode = this.Head.Next;
                this.Head.Next = null;
                this.Head      = nextNode;
            }
            else
            {
                SllNode <T> current = this.Head;
                while (current.Next != node)
                {
                    current = current.Next;
                }
                current.Next = node.Next;
            }

            return(node);
        }
コード例 #30
0
        public void DeleteNodesAtDistance(int distance)
        {
            SllNode <T> current = Head;
            SllNode <T> prev    = null;

            while (current != null)
            {
                //Skip distance nodes
                for (int i = 1; i < distance; i++)
                {
                    prev    = current;
                    current = current.Next;
                }

                if (current != null && prev != null)
                {
                    prev.Next = current.Next;
                    current   = prev.Next;
                }
            }
        }