public Node(int i)
        {

            this.info = i;
            this.link = null;

        }
        internal void InsertAtTheBeginning(int data)
        {
            Node temp = new Node(data);

            temp.link = start;
            start = temp;

        }
        internal void InsertAtTheEnd(int data)
        {
            Node p;

            Node temp = new Node(data);

            if (start == null)
            {
                start = temp;
                return;
            }

            p = start;

            while (p.link != null)
            {
                p = p.link;
            }

            p.link = temp;

        }
        internal void InsertAtSpecifiedAfterNode(int data, int x)
        {
            Node p = start;

            while (p != null)
            {
                if (p.info == x)
                {
                    break;
                }

                p = p.link;
            }

            if (p == null)
            {
                Console.WriteLine( x + " is not in the List :");
            }


            else
            {
                Node temp = new Node(data);

                temp.link = p.link;

            }
        }
        internal void InsertAtSpecifiedBeforeNode(int data, int x)
        {
            Node temp;

            if (start == null)
            {
                Console.WriteLine("The List is empty: ");
                return;
            }

            if (x == start.info)
            {
                temp = new Node(data);
                temp.link = start;
                start = temp;
                return;
            }

            Node p = start;

            while (p != null)
            {
                if (p.link.info == x)
                {
                    break;
                }

                p = p.link;
            }

            if (p.link == null)
            {
                Console.WriteLine( x + " is not presont in the list.");
            }

            else
            {
                temp = new Node(data);
                temp.link = p.link;
                p.link = temp;
            }


        }
        internal void InsertAtSpecifiedPosition(int data, int x)
        {
            Node temp;

            int i;

            if (x == 1)
            {
                temp = new Node(data);
                temp.link = start;
                start = temp;

                return;

            }

            Node p = start;

            for ( i = 1; i < x - 1 &&  p != null; i++)
            {
                p = p.link;
            }

            if (p == null)
            {
                Console.WriteLine("you can insert only up to ." + i + "position.");
            }

            else
            {
                temp = new Node(data);
                temp.link = p.link;
                p.link = temp;
            }

        }
        internal void DeleteFirstNode()
        {
            if (start == null)
            {
                return;
            }

            start = start.link;
        }
 // Errors !!
 public void MergeSort()
 {
     start = MergeSortRec(start);
 }
        internal void DeleteAnyNode(int data)
        {
            if (start == null)
            {
                Console.WriteLine("The list is empty.");
                return;
            }

            if (start.info == data)
            {
                start = start.link;
                return;
            }

            Node p = start;

            while (p.link != null)
            {
                if (p.link.info == data)
                {
                    break;                    
                }

                p = p.link;
            }

            if (p.link == null)
            {
                Console.WriteLine("Element not found " + data + "not in the list.");
            }

            else
            {
                p.link = p.link.link;
            }
        }
        internal void Reverse()
        {
            Node prev, p, next;

            prev = null;
            p = start;

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

            start = prev;
        }
        internal void BubbleSortByExchengingLinks()
        {
            Node end, r, p, q, temp;
            p = null;

            for (end = null; end != start.link;end = p ) 
            {
                for (r = p = start; p.link != end; r = p,p = p.link )
                {
                    q = p.link;

                    if (p.info > q.info)
                    {
                        p.link = q.link;
                        q.link = p;

                        if (p != start)
                        {
                            r.link = q;
                        }

                        else
                        {
                            start = q;
                        }

                        temp = p;
                        p = q;
                        q = temp;

                    }
                }
            }
        }
        //p = listStart;
        private Node DivideTheList(Node p)
        {
            Node q = p.link.link;

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

            Node startTwo = p.link;
            p.link = null;

            return startTwo;

        }
        // pOne =startOne ; pTwo = startTwo;
        private Node MergeTwo(Node pOne, Node pTwo)
        {
            
            // pOne = start ; pTwo = node;
            Node startMerge;

            if (pOne.info <= pTwo.info)
            {
                startMerge = pOne;
                pOne = pOne.link;
            }

            else
            {
                startMerge = pTwo;
                pTwo = pTwo.link;

            }

            Node pM = startMerge;

            while (pOne != null && pTwo != null)
            {
                if (pOne.info <= pTwo.info)
                {
                    pM.link = pOne;
                    pM = pM.link;
                    pOne = pOne.link;
                }

                else
                {
                    pM.link = pTwo;
                    pM = pM.link;
                    pTwo = pTwo.link;
                }
            }

            if (pTwo == null)
            {
                pM.link = pTwo;
            }

            else
            {
                pM.link = pOne;
            }

            return startMerge;

        }
        private Node MergeSortRec(Node listStart)
        {
            //if the list is empty or has...
            if (listStart == null || listStart.link == null)
            {
                return listStart;
            }

            //if more than one element;
            Node startOne = listStart;
            Node startTwo = DivideTheList(listStart);

            startOne = MergeSortRec(startOne);
            startTwo = MergeSortRec(startTwo);

            Node startM = MergeTwo(startOne,startTwo);

            return startM;
        }
        // Error !
        private Node MergeOne(Node pOne, Node pTwo)
        {

            Node startMerge;

            if (pOne.info <= pTwo.info)
            {
                startMerge = new Node(pOne.info);
                pOne = pOne.link;
            }

            else
            {
                startMerge = new Node(pTwo.info);
                pTwo = pTwo.link;
            }

            Node pM = startMerge;

            while (pOne != null && pTwo != null)
            {
                if (pOne.info <= pTwo.info)
                {
                    pM.link = new Node(pOne.info);
                    pOne = pOne.link;
                }

                else
                {
                    pM.link = new Node(pTwo.info);
                    pTwo = pTwo.link;
                }

                pM = pM.link;

                // if the Second list has finished and element left in the first list.
                while (pOne != null)
                {
                    pM.link = new Node(pOne.info);
                    pOne = pOne.link;
                    pM = pM.link;
                }

                //If first list has finished and elements left in second list.
                while (pTwo != null)
                {
                    pM.link = new Node(pTwo.info);
                    pTwo = pTwo.link;
                    pM = pM.link;
                }

                return startMerge;

            }

        }
        internal void DeleteLastNode()
        {
            if (start == null)
            {
                return;
            }

            if (start.link == null)
            {
                start = null;
                return;
            }

            Node p = start;

            while (p.link.link != null)
            {
                p = p.link;
                p.link = null;
            }
        }
 public SingleLinkedList()
 {
     this.start = null;
 }