最小の数が最初に追加されたときにのみ、並べ替えリンクリスト上のJavaマージソート

chinloyal:

私は私のリンクリスト内の番号を挿入すると、それに最初に追加された数が最小であるときにのみ、すべてをソートします。これは私が取得していますことを予期しない動作です。

473、23、390、25、200 - 私はこの順序で番号を挿入します

Iその上で、それを表示するようにソートリストならば、私はこれを取得 - 200、390、473

私は200 900に変更する場合は、ソートリストは、それだけで900を表示します

私は1(以下23以上のもの)のようなリストの中で最も小さい番号に200を変更したときに動作しますそれだけで、それは私の右出力1、23、25、390、473を与えます

私は、リストの後ろに要素を挿入し、リンクリストの場合、これはコードです:

public void insertAtBack(IntegerElement elem) {
    if (isFull()) {
        System.out.println("Unable to insert node into full list");
    } else {
        Node temp = new Node(elem);
        if (isEmpty()) {
            head = temp;
        } else {
            Node current = head;
            while (current.getLink() != null) {
                current = current.getLink();
            }
            current.setLink(temp);
        }
    }

}

そして、これは私がマージソートするために使用するコードです:

public Node getMiddle(Node node) {
    if (node == null) 
        return node;

    Node fastptr = node.getLink(); 
    Node slowptr = node; 

    // Move fastptr by two and slow ptr by one 
    // Finally slowptr will point to middle node 
    while (fastptr != null) { 
        fastptr = fastptr.getLink(); 
        if(fastptr != null) { 
            slowptr = slowptr.getLink(); 
            fastptr = fastptr.getLink(); 
        } 
    } 

    return slowptr; 
}

public Node merge(Node left, Node right)  { 

    Node tempHead = new Node(), curr;

    curr = tempHead;

    while(left != null && right != null) {
        if(left.getData().getValue() <= right.getData().getValue()) {
            curr.setLink(left);
            left = left.getLink();
        }else {
            curr.setLink(right);
            right = right.getLink();
        }

        curr = curr.getLink();
    }

    curr.setLink((left == null) ? right : left);

    return tempHead.getLink();

}

/**
 * This method utilizes merge sort algorithm
 * 
 * @param node - Pass in head first
 * 
 */
public Node sort(Node node) {
    // Base case : if head is null 
    if (node == null || node.getLink() == null)
        return node; 

    // get the middle of the list 
    Node middle = getMiddle(node);
    Node nextofmiddle = middle.getLink();

    // set the next of middle node to null 
    middle.setLink(null);

    // Merge the left and right lists 
    return merge(sort(node), sort(nextofmiddle));
}

すべてのヘルプは高く評価され

ggorlen:

あなたのソート・ルーチンは素晴らしく見えます。バグはあなたのソートルーチンから復帰されている方法であるように思われます。あなたの並べ替えを呼び出した場合、それはその場でソートであるかのように、すなわち

sort(head);
System.out.println(head);

古い頭はで返された新しいヘッドに更新されませんsort()あなたのテストケースに表示されているノードは、常に古い頭が何であれで始まるどのように注意してください。これは、表示されたソートされていない、リスト内の古い頭があなたの最後の例のように、ソートされたリストに、新たなヘッドであることを起こる場合は仕事に。一方、古いヘッドノードがソート中に移動されている場合は、あなただけの古い頭が以降に移動どこからリストの残りの部分が表示されます。彼らはスコープの外に行くときに、リストアップの前から古い頭のノードはガベージコレクトになります。

修正はから返された頭に、発信者にあなたのリストの先頭を設定することでsort()、リストの新しいヘッドであり、:

head = sort(head);
System.out.println(head);

ここでは、問題を説明するために、あなたのエラーを再現書かれた再あなたのコードは次のとおりです。

class Main {
    public static void main(String[] args) {
        Node head = new Node(200, new Node(25, new Node(473, new Node(23, new Node(390, null)))));

        System.out.println("Example 1 (correct):");
        System.out.println(head);
        head = sort(head);
        System.out.println(head);

        head = new Node(200, new Node(25, new Node(473, new Node(23, new Node(390, null)))));

        System.out.println("\nExample 1 (incorrect):");
        System.out.println(head);
        sort(head);
        System.out.println(head);

        head = new Node(900, new Node(25, new Node(473, new Node(23, new Node(390, null)))));

        System.out.println("\n\nExample 2 (correct):");
        System.out.println(head);
        head = sort(head);
        System.out.println(head);

        head = new Node(900, new Node(25, new Node(473, new Node(23, new Node(390, null)))));

        System.out.println("\nExample 2 (incorrect):");
        System.out.println(head);
        sort(head);
        System.out.println(head);

        head = new Node(1, new Node(25, new Node(473, new Node(23, new Node(390, null)))));
        System.out.println("\n\nExample 3 (accidentally works, because the old head is still the new head):");
        System.out.println(head);
        sort(head);
        System.out.println(head);
    }

    static Node getMiddle(Node node) {
        Node fastptr = node.link; 
        Node slowptr = node; 

        while (fastptr != null) { 
            fastptr = fastptr.link; 

            if (fastptr != null) { 
                slowptr = slowptr.link;
                fastptr = fastptr.link; 
            }
        } 

        return slowptr; 
    }

    static Node merge(Node left, Node right) { 
        Node temp = new Node(-1, null);
        Node curr = temp;

        while (left != null && right != null) {
            if (left.data < right.data) {
                curr.link = left;
                left = left.link;
            }
            else {
                curr.link = right;
                right = right.link;
            }

            curr = curr.link;
        }

        curr.link = left == null ? right : left;
        return temp.link;
    }

    static Node sort(Node node) {
        if (node == null || node.link == null) {
            return node; 
        }

        Node middle = getMiddle(node);
        Node next = middle.link;
        middle.link = null;
        return merge(sort(node), sort(next));
    }
}

class Node {
    public int data;
    public Node link;

    public Node(int data, Node link) {
        this.data = data;
        this.link = link;
    }

    public String toString() {
        return this.data + (this.link != null ? "->" + this.link : "");
    }
}

出力:

Example 1 (correct):
200->25->473->23->390
23->25->200->390->473

Example 1 (incorrect):
200->25->473->23->390
200->390->473


Example 2 (correct):
900->25->473->23->390
23->25->390->473->900

Example 2 (incorrect):
900->25->473->23->390
900


Example 3 (accidentally works, because the old head is still the new head):
1->25->473->23->390
1->23->25->390->473

それを試してみてください!

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=192833&siteId=1