简体   繁体   中英

Linked List natural mergeSort

So Natural mergeSort is a variation on mergeSort that instead of splitting the list into halves, you iterate through the list, make 2 new temp lists that are "naturally sorted" and then sort those 2 lists. eg List = 1, 3, 2, 4, 5, null

The first temp list == 1, 3 because 1 < 3, but 3 is not < 2
The second temp list == 2, 4, 5

Next step is to compare first temp list with second temp list

if( firstTemp > secondTemp) 
     swap;    

My problem comes from creating these 2 separate lists. When I create the 2 new lists, it's erasing my original list. Also I can't seem to get my counter right for creating the size of the lists. A new list doesn't seem to act like a new list because the counter keeps incrementing from the original list to the new lists.
Like the eg above,

ogList.size = 5
then
firstTemp.size = 7
secondTemp.size = 10

When it should be

firstTemp.size = 2
and
secondTemp.size = 3

package mergesortlinkedlist;

public class MergeSortLinkedList {

static LinkedList list = new LinkedList();

public static void main(String[] args) {

    //
    // start linked list
    //
    LinkedList.push(list, 1);
    LinkedList.push(list, 3);
    LinkedList.push(list, 2);
    LinkedList.push(list, 4);
    LinkedList.push(list, 5);


    list.printList(list);


    System.out.println("list size = " + list.head.getCounter());

    naturalMerge(list);

}

public static void naturalMerge(LinkedList front) {
    LinkedList set1 = new LinkedList();
    LinkedList set2 = new LinkedList();
    LinkedList temp = front;

    //get first temp list
    while (temp != null) {

        if (temp.head.data < temp.head.next.data) {
            LinkedList.push(set1, temp.head.data);
            temp.head = temp.head.next;

        } else {
            LinkedList.push(set1, temp.head.data);
            temp.head = temp.head.next;
            break;

        }
    }

    //get second temp list
    while (temp != null) {

        if (temp.head.data < temp.head.next.data) {
            LinkedList.push(set2, temp.head.data);
            temp.head = temp.head.next;
        } else {
            LinkedList.push(set2, temp.head.data);
            temp.head = temp.head.next;
            break;

        }
    }

    mergeSwap(set1, set2);
}


public static void mergeSwap(LinkedList set1, LinkedList ){   

    //template code to swap the naturally sorted temp lists
    }
 }
}



public class LinkedList {

public Node head;

public static class Node {

    public Node next = null;
    public Integer data;
    public static int counter = 0;

    Node() {

    }

    Node(int d) {
        this.data = d;
    }

    public void setCounter(int n) {
        counter += n;
    }

    public int getCounter() {
        return counter;
    }
}

public static void push(LinkedList list, int data) {
    // Create a new node with given data 
    Node new_node = new Node(data);
    new_node.next = null;

    // If the Linked List is empty, 
    // then make the new node as head 
    if (list.head == null) {
        list.head = new_node;
        new_node.setCounter(1);

    } else {
        // Else traverse till the last node 
        // and insert the new_node there 
        Node last = list.head;
        while (last.next != null) {
            last = last.next;
        }

        // Insert the new_node at last node 
        last.next = new_node;
        new_node.setCounter(1);

    }

    // Return the list by head 
    //return list; 
}

I'm just wondering if this version of my code is possible for creating separate lists for natural mergeSort. Am I able to use this code to make new lists without destroying the original list?

Ultimately, I want my list = 1,2,3,4,5,null

Ok well I changed some things, it's not able to do recurssive calls, which makes me think the logic isn't working right, but I'm still able to sort the list.
Instead of calling

naturalMerge(list); 

after swapping nodes, I do it from main. The only reason is because for some reason I get a null pointer exception.
I'd like to come back to this and make it work better, but for now it'll probably do for getting my assignment turned in.

package mergesortlinkedlist;

public class MergeSortLinkedList {

    // static Node first = new Node();
    static LinkedList list = new LinkedList();

    public static void main(String[] args) {
        // start linked list
        list.add(list, 1);
        list.add(list, 5);
        list.add(list, 3);
        list.add(list, 4);
        list.add(list, 2);
        list.add(list, 100);
        list.add(list, 76);
        list.add(list, -6);

        list.printList(list);

        naturalMerge(list);

        list.printList(list);

        naturalMerge(list);

        list.printList(list);

        naturalMerge(list);

        list.printList(list);

    }

    public static void naturalMerge(LinkedList front) {
        LinkedList set1 = new LinkedList();
        LinkedList set2 = new LinkedList();
        LinkedList temp = front;
        int size1 = 0;
        int sortCounter = 0;        //if sortCounter != 0, then there is more to sort

        //get first temp list
        while (temp.head.data != null) {

            if (temp.head.data < temp.head.next.data) {

                set1.add(set1, temp.head.data);
                size1++;
                temp.head = temp.head.next;

            } else {
                set1.add(set1, temp.head.data);
                size1++;
                temp.head = temp.head.next;
                break;

           }
        }

        //get second temp list
        while (temp.head != null) {

            if (temp.head.next == null) {
                set2.add(set2, temp.head.data);
                temp.head = temp.head.next;
                break;
            }
            if (temp.head.data < temp.head.next.data) {

                set2.add(set2, temp.head.data);

                temp.head = temp.head.next;

            } else {

                set2.add(set2, temp.head.data);

                temp.head = temp.head.next;

                break;

            }
        }

        mergeSwap(set1, set2, size1);
    }

    public static void mergeSwap(LinkedList set1, LinkedList set2, int size1)  {

        System.out.println();
        LinkedList temp = set1;
        LinkedList temp2 = set2;


        while (temp.head != null && temp2.head != null) {

            if (temp.head.data < temp2.head.data) {

                list.add(list, temp.head.data);
                temp.head = temp.head.getNext();    //increment temp

            } else {

                list.add(list, temp2.head.data);
                temp2.head = temp2.head.getNext();  //increment temp2

            }

            //if one list is empty, break loop and add remaining nodes
            if (temp.head == null || temp2.head == null) {
               break;
            }

        }
        //check which list is empty, and add the remaining nodes to original list
        if (temp.head == null) {
            while (temp2.head != null) {
               list.add(list, temp2.head.data);
               temp2.head = temp2.head.getNext();
           }
        } else {
            while (temp.head != null) {
               list.add(list, temp.head.data);
               temp.head = temp.head.getNext();
            }
        }

        //naturalMerge(list);     //this call breaks the code, but why? How is it any different from the method call in main?
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM