Пример #1
0
        public static void PrintNode(this MyLinkedListNode myLinkListNode, String header = "")
        {
            if (!string.IsNullOrEmpty(header))
            {
                Console.WriteLine(header);
            }

            if (myLinkListNode != null)
            {
                Console.WriteLine($"Node value is '{myLinkListNode.Data}'");
            }
            else
            {
                Console.WriteLine($"Node does not exist!!!");
            }
        }
            public int NthToLast_1_Recurssive_InternalCounter(MyLinkedListNode head, int n)
            {
                if (n == 0 || head == null)
                {
                    return(0);
                }
                Console.WriteLine($"head.Data='{head.Data}' n='{n}'");
                var k = NthToLast_1_Recurssive_InternalCounter(head.Next, n) + 1;

                if (k == n)
                {
                    Console.WriteLine($"{n}th to last node is { head.Data} ");
                }
                Console.WriteLine($"*** n='{n}' k='{k}'");
                return(k);
            }
            public static Result getTailAndSize(MyLinkedListNode list)
            {
                if (list == null)
                {
                    return(null);
                }

                int size = 1;
                MyLinkedListNode current = list;

                while (current.Next != null)
                {
                    size++;
                    current = current.Next;
                }
                return(new Result(current, size));
            }
            public void Run()
            {
                /* Create linked list */
                int[]            vals  = { -1, -2, 0, 1, 2, 3, 4, 5, 6, 7, 8 };
                MyLinkedListNode list1 = CreateLinkedListFromArray(vals);

                list1.PrintForward("list1");
                int[]            vals2 = { 12, 14, 15 };
                MyLinkedListNode list2 = CreateLinkedListFromArray(vals2);

                list2.PrintForward("list2");
                //adding some common elements
                list2.Next.Next = list1.Next.Next.Next.Next;
                list2.PrintForward("list2");
                MyLinkedListNode intersection = findIntersection(list1, list2);

                intersection.PrintForward("intersection");
            }
            public MyLinkedListNode NthToLast_2_Recurssive_ExternalCounter(MyLinkedListNode head, int n, ref int i)
            {
                if (head == null)
                {
                    return(null);
                }
                Console.WriteLine($"head.Data='{head.Data}' n='{n}' i='{i}'");
                var node = NthToLast_2_Recurssive_ExternalCounter(head.Next, n, ref i);

                i = i + 1;
                Console.WriteLine($"***head.Data='{head.Data}' n='{n}' i='{i}' node.Data='{node.NodeValue()}'");

                if (i == n)
                {
                    Console.WriteLine($"{n}th element is '{head.Data}'");
                    return(head);
                }
                return(node);
            }
            public MyLinkedListNode Partition2(MyLinkedListNode node, int pivot)
            {
                MyLinkedListNode beforeStart = null;
                MyLinkedListNode afterStart  = null;

                /* Partition list */
                while (node != null)
                {
                    var next = node.Next;

                    if ((int)node.Data < pivot)
                    {
                        /* Insert node into start of before list */
                        node.Next   = beforeStart;
                        beforeStart = node;
                    }
                    else
                    {
                        /* Insert node into front of after list */
                        node.Next  = afterStart;
                        afterStart = node;
                    }
                    node = next;
                }

                /* Merge before list and after list */
                if (beforeStart == null)
                {
                    return(afterStart);
                }

                var head = beforeStart;

                while (beforeStart.Next != null)
                {
                    beforeStart = beforeStart.Next;
                }

                beforeStart.Next = afterStart;

                return(head);
            }
        /// <summary>
        /// Use two pointers, walker and runner.
        /// walker moves step by step.runner moves two steps at time.
        /// if the Linked List has a cycle walker and runner will meet at some point.
        /// </summary>
        /// <param name="head"></param>
        /// <returns></returns>
        public static bool CycleExists(MyLinkedListNode head)
        {
            if (head == null)
            {
                return(false);
            }
            MyLinkedListNode walker = head;
            MyLinkedListNode runner = head;

            while (runner.Next != null && runner.Next.Next != null)
            {
                walker = walker.Next;
                runner = runner.Next.Next;
                if (walker == runner)
                {
                    return(true);
                }
            }
            return(false);
        }
        /// <summary>
        /// Changing pointer in reverse direction
        /// </summary>
        /// <param name="head"></param>
        /// <returns></returns>
        public MyLinkedListNode ReverseLinkedListIterative(MyLinkedListNode head)
        {
            /* iterative solution */
            MyLinkedListNode newHead = null;

            while (head != null)
            {
                //head.PrintForward("head");
                //Updating pointer
                MyLinkedListNode nextNode = head.Next;
                head.Next = newHead;

                //Link to New node
                //Moving both heads
                newHead = head;
                head    = nextNode;
                //newHead.PrintForward("newHead");
            }
            return(newHead);
        }
        public void DeleteDups_UsingTwoPointer(MyLinkedListNode head)
        {
            Console.WriteLine($"{this.GetType().FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}\n");
            head.PrintForward("List-Before:");

            int tapB = 0;

            if (head == null)
            {
                return;
            }

            var current = head;

            while (current != null)
            {
                /* Remove all future nodes that have the same value */
                var runner = current;

                while (runner.Next != null)
                {
                    tapB++;
                    Console.WriteLine($"current.Data '{current.Data}' runner.Next.Data: '{runner.Next.Data}'");

                    if (runner.Next.Data.Equals(current.Data))
                    {
                        Console.WriteLine($"Removing runner '{runner.Next.Data}'");
                        runner.Next = runner.Next.Next;
                        head.PrintForward();
                    }
                    else
                    {
                        runner = runner.Next;
                    }
                }
                current = current.Next;
            }
            head.PrintForward("List-After\n");
            Console.WriteLine("-------------------------------------------------------");
        }
            public MyLinkedListNode Partition4(MyLinkedListNode listHead, int pivot)
            {
                MyLinkedListNode leftSubList      = null;
                MyLinkedListNode rightSubList     = null;
                MyLinkedListNode rightSubListHead = null;
                MyLinkedListNode pivotNode        = null;

                var currentNode = listHead;

                while (currentNode != null)
                {
                    var nextNode = currentNode.Next;
                    currentNode.Next = null;

                    if ((int)currentNode.Data < pivot)
                    {
                        leftSubList = leftSubList == null
                            ? currentNode
                            : leftSubList = leftSubList.Next = currentNode;
                    }
                    else if ((int)currentNode.Data > pivot)
                    {
                        rightSubList           = rightSubList == null
                            ? rightSubListHead = currentNode
                            : rightSubList     = rightSubList.Next = currentNode;
                    }
                    else
                    {
                        pivotNode = currentNode;
                    }

                    currentNode = nextNode;
                }

                pivotNode.Next   = rightSubListHead;
                rightSubListHead = pivotNode;
                leftSubList.Next = rightSubListHead;

                return(listHead);
            }
        /// <summary>
        /// Use two pointers, walker and runner.
        /// walker moves step by step.runner moves two steps at time.
        /// if the Linked List has a cycle walker and runner will meet at some point.
        /// </summary>
        /// <param name="head"></param>
        /// <returns>runner (not slower)</returns>
        public static MyLinkedListNode CycleExistsReturnRunner(MyLinkedListNode head)
        {
            if (head == null)
            {
                return(null);
            }
            MyLinkedListNode walker = head;
            MyLinkedListNode runner = head;

            while (runner.Next != null && runner.Next.Next != null)
            {
                walker = walker.Next;
                runner = runner.Next.Next;
                if (walker == runner)
                {
                    Console.WriteLine($"CycleExists: True runner.Data:{runner.Data}");
                    return(runner);
                }
                ;
            }
            return(null);
        }
        public static MyLinkedListNode MergeTwoLists_Int(MyLinkedListNode l1, MyLinkedListNode l2)
        {
            if (l1 == null)
            {
                return(l2);
            }
            if (l2 == null)
            {
                return(l1);
            }

            if ((int)l1.Data < (int)l2.Data)
            {
                l1.Next = MergeTwoLists_Int(l1.Next, l2);
                return(l1);
            }
            else
            {
                l2.Next = MergeTwoLists_Int(l2.Next, l1);
                return(l2);
            }
        }
        /// <summary>
        /// Use two pointers, walker and runner.
        /// walker moves step by step.runner moves two steps at time.
        /// if the Linked List has a cycle walker and runner will meet at some point.
        /// </summary>
        /// <param name="head"></param>
        /// <returns></returns>
        public static MyLinkedListNode CycleFindBeginning(MyLinkedListNode head)
        {
            var runner = CycleExistsReturnRunner(head);

            if (runner != null)
            {
                /* Move slow to Head. Keep fast at Meeting Point. Each are k steps
                 * /* from the Loop Start. If they move at the same pace, they must
                 * meet at Loop Start. */
                var walker = head;

                while (walker != runner)
                {
                    Console.WriteLine($"*slow.Data{walker.Data}");
                    Console.WriteLine($"*fast.Data{runner.Data}");
                    walker = walker.Next;
                    runner = runner.Next;
                }
            }
            // Both now point to the start of the loop.
            return(runner);
        }
            public PartialSum AddListsHelper(MyLinkedListNode list1, MyLinkedListNode list2)
            {
                if (list1 == null && list2 == null)
                {
                    return(new PartialSum());
                }

                var sum = new PartialSum();
                var val = 0;

                if (list1 != null)
                {
                    sum = AddListsHelper(list1.Next, list2.Next);
                    val = sum.Carry + (int)list1.Data + (int)list2.Data;
                }

                var fullResult = insertBefore(sum.Sum, val % 10);

                sum.Sum   = fullResult;
                sum.Carry = val / 10;

                return(sum);
            }
            public Result NthToLast_3_Recurssive_ExternalCounterAndNode_Helper(MyLinkedListNode head, int k)
            {
                if (head == null)
                {
                    return(new Result(null, 0));
                }
                head.PrintForward($"*** k='{k}'  result.Node='{head.NodeValue()}'");
                var result = NthToLast_3_Recurssive_ExternalCounterAndNode_Helper(head.Next, k);

                head.PrintForward($"*** k='{k}' result.Count='{result.Count}' result.Node='{result.Node.NodeValue()}'");

                if (result.Node == null)
                {
                    result.Count++;

                    if (result.Count == k)
                    {
                        Console.WriteLine($"{k}th element is '{head.Data}'");
                        result.Node = head;
                    }
                }

                return(result);
            }
        public MyLinkedListNode Cycle_Create()
        {
            const int listLength = 10;
            const int k          = 3;

            // Create linked list
            var nodes = new MyLinkedListNode[listLength];

            for (var i = 1; i <= listLength; i++)
            {
                nodes[i - 1] = new MyLinkedListNodeDoubly(i, null, i - 1 > 0 ? (MyLinkedListNodeDoubly)nodes[i - 2] : null);
                Console.Write("{0} -> ", nodes[i - 1].Data);
            }
            // Create loop;
            Console.WriteLine($"\n Create loop: nodes[listLength - 1].Next = nodes[listLength - k - 1]");
            nodes[listLength - k - 1].PrintForward("nodes[listLength - k - 1]");
            nodes[listLength - 1].PrintForward("nodes[listLength - 1]");

            nodes[listLength - 1].Next = nodes[listLength - k - 1];
            Console.WriteLine("\n{0} -> {1}", nodes[listLength - 1].Data, nodes[listLength - k - 1].Data);
            Console.WriteLine("Nodes:\n");

            return(nodes[0]);
        }
            public bool IsPalindrome_UsingStack(MyLinkedListNode head)
            {
                var fast = head;
                var slow = head;

                var stack = new Stack <int>();

                while (fast != null && fast.Next != null)
                {
                    stack.Push((int)slow.Data);
                    slow = slow.Next;
                    //traverse with two elements so that stack will have half values
                    fast = fast.Next.Next;
                }

                /* Has odd number of elements, so skip the middle */
                if (fast != null)
                {
                    slow = slow.Next;
                }

                //Traverse other half stack and compare elements
                while (slow != null)
                {
                    var top = stack.Pop();
                    Console.WriteLine(slow.Data + " " + top);

                    if (top != (int)slow.Data)
                    {
                        return(false);
                    }
                    slow = slow.Next;
                }

                return(true);
            }
        public override void SetNext(MyLinkedListNode n)
        {
            MyLinkedListNodeSingly newNextNode = (MyLinkedListNodeSingly)n;

            SetNext(newNextNode);
        }
 public abstract void SetNext(MyLinkedListNode n);
 public Result(MyLinkedListNode tail, int size)
 {
     this.tail = tail;
     this.size = size;
 }
 public Result(MyLinkedListNode node, int count)
 {
     Node  = node;
     Count = count;
 }
 public Result(MyLinkedListNode node, bool res)
 {
     Node   = node;
     result = res;
 }
 public abstract bool DeleteNode(MyLinkedListNode node);
 public MyLinkedListNode ReverseLinkedListRecursive(MyLinkedListNode head)
 {
     /* recursive solution */
     return(ReverseLinkedListRecursiveInt(head, null));
 }
        public void DeleteDupsC_InProgress(MyLinkedListNode head)
        {
            int tabC = 0;

            head.PrintForward("List-Before\n");
            Console.WriteLine($"{this.GetType().FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}\n");

            if (head == null)
            {
                return;
            }

            var previous = head;
            //Next element
            var current = previous.Next;

            while (current != null)
            {
                // Look backwards for dups, and remove any that you see.
                var runner = head;

                head.PrintForward();
                current.PrintForward();
                runner.PrintForward();

                while (runner != current && current != null)
                {
                    runner.PrintForward();

                    tabC++;
                    Console.WriteLine($"@@current.Data '{current.Data}' runner.Data: '{runner.Data}'");
                    if (runner.Data.Equals(current.Data))
                    {
                        head.PrintForward();
                        current.PrintForward();
                        previous.PrintForward();
                        //Console.WriteLine($"@@Removing current '{current.Data}'");
                        //urrent = current.Next;

                        var temp = current.Next;
                        previous.Next = temp;
                        current       = temp;
                        //Console.WriteLine($"***Inner current {current.PrintForward()}");
                        //previous = current;
                        //current = temp;

                        /* We know we can't have more than one dup preceding
                         * our element since it would have been removed
                         * earlier. */
                        //break;
                        //Console.WriteLine($"{head.PrintForward()}");
                    }

                    runner = runner.Next;
                    runner.PrintForward();
                }

                /* If runner == current, then we didn�t find any duplicate
                 * elements in the previous for loop.  We then need to
                 * increment current.
                 * If runner != current, then we must have hit the �break�
                 * condition, in which case we found a dup and current has
                 * already been incremented.*/
                if (runner == current)
                {
                    head.PrintForward();
                    previous.PrintForward();
                    current.PrintForward();
                    runner.PrintForward();
                    previous = current;
                    current  = current.Next;
                    previous.PrintForward();
                    //Console.WriteLine($"@@@current {current.PrintForward()}");
                }
            }
            head.PrintForward("List-After\n");
            Console.WriteLine("-------------------------------------------------------");
        }