简体   繁体   English

合并排序的链接列表(JAVA)中出现意外结果

[英]Unexpected result in Merge Sort for linked list (JAVA)

class Node {

    int data;
    Node next;

    public Node(int a) {data = a; next = null;}
}

public class List {

    public Node head;

    public List () {
        head = null;
    }

    public boolean isEmpty() {
        return head == null;
    }

    public void insertAtFront(int a) {
        Node node = new Node(a);
        node.next = head;
        head = node;
    }

    public void insertAtEnd(int a) {
        Node node = new Node(a);
        // this check cannot be omitted
        // otherwise you get NullPointerException on an empty list.
        if (head == null) {
            insertAtFront(a);
            return;
        }
        Node cur = head;
        while(cur.next != null) {
            cur = cur.next;
        }
        cur.next = node;
    }

    public void insertAfter(Node node, int a) {
        Node newNode = new Node(a);
        if (node == null) {
            System.out.println("Oops...");
            return;
        }
        newNode.next = node.next;
        node.next = newNode;
    }

    public Node search(int a) {
        Node cur = head;
        while(cur != null && cur.data != a) cur = cur.next;
        return cur;
    }

    public int deleteFirst() {
        if (head == null) {
            System.out.println("Oops...");
            return -1;
        }
        Node node = head;
        head = head.next;
        node.next = null;
        return node.data;
    }

    public int deleteLast() {
        if (head == null || head.next == null)
            return deleteFirst();
        Node second = head;
        Node cur = second.next;
        // when the thile loop finishes,
        // cur points to the last node.
        while(cur.next != null) {
            second = cur;
            cur = cur.next;
        }
        second.next = null;
        return cur.data;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        Node cur = head;
        while(cur != null) {
            sb.append(cur.data);
            if (cur.next != null) sb.append(", ");
            cur = cur.next;
        }
        return sb.toString();
    }

    private Node merge(Node head1, Node head2) {
        Node dummy = new Node(0);
        Node tail = dummy;
        while (head1 != null && head2 != null) {
            if (head1.data < head2.data) {
                tail.next = head1;
                head1 = head1.next;
            } else {
                tail.next = head2;
                head2 = head2.next;
            }
            tail = tail.next;
        }
        if (head1 != null) {
            tail.next = head1;
        } else {
            tail.next = head2;
        }

        return dummy.next;
    }

    public Node mergesort(Node head) {
        if (head == null || head.next == null) {
            return head;
        }

        Node mid = findMiddle(head);
        Node right = mergesort(mid.next);
        mid.next = null;
        Node left = mergesort(head);

        return merge(left, right);
    }

    private Node findMiddle(Node head) {
        Node slow = head, fast = head.next;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }

    public static void main(String[] args) {
        List list = new List();
        list.insertAtFront(37);
        list.insertAtFront(99);
        list.insertAtFront(12);
        // the list at page 88 of the slides.
        System.out.println(list);
        list.insertAtFront(75);
        System.out.println(list);
        list.insertAtEnd(38);
        System.out.println(list);
        list.insertAfter(list.search(12), 85);
        System.out.println(list);
        list.mergesort(list.head);
        System.out.println("after sorting: " + list + "\n");
        System.out.println("delete the first, which is " + list.deleteFirst());
        System.out.println(list);
        System.out.println("delete the last, which is " + list.deleteLast());
        System.out.println(list);
    }
}

Here is my code for linked list in merge sort. 这是我用于合并排序的链表的代码。 However, only the rear part of the linked list was displayed. 但是,仅显示链接列表的后半部分。 what is the problem....? 问题是什么....?

Using Intellij: 使用Intellij:

12, 99, 37 12、99、37

75, 12, 99, 37 75、12、99、37

75, 12, 99, 37, 38 75、12、99、37、38

75, 12, 85, 99, 37, 38 75、12、85、99、37、38

after sorting: 75, 85, 99 排序后:75、85、99

delete the first, which is 75 删除第一个,即75

85, 99 85、99

delete the last, which is 99 删除最后一个,即99

85 85

while getting return from mergesort() in main method you are not changing the head of the list there. 从main方法中的mergesort()获得收益的同时,您没有在此更改列表的标题。 So in your case the list is sorted but head remains 75 only and thing work right according to the code 因此,在您的情况下,列表已排序,但head仅保留75,并且根据代码工作正常

In main method Replace: list.mergesort(list.head); 在主要方法中,替换为:list.mergesort(list.head); with: list.head = list.mergesort(list.head); 使用:list.head = list.mergesort(list.head);

I refactored your code, see below. 我重构了您的代码,请参见下文。 Hopefully it's pretty self explanatory. 希望这是自我解释。

public class List {

    public Node head;

    public List () {
        head = null;
    }

    public boolean isEmpty() {
        return head == null;
    }

    public void insertAtFront(int a) {
        Node node = new Node(a);
        node.next = head;
        head = node;
    }

    public void insertAtEnd(int a) {
        Node node = new Node(a);
        if (head == null) {
            head = node;
        }
        else {
            Node cur = head;
            while(cur.next != null) {
                cur = cur.next;
            }
            cur.next = node;
        }
    }

    public void insertAfter(Node predecessor, int a) {
        if (predecessor == null) {
            throw new IllegalArgumentException("Predecessor cannot be null");
        }
        Node node = new Node(a);
        node.next = predecessor.next;
        predecessor.next = node;
    }

    /** returns null if a is not found */
    public Node findFirst(int a) {
        Node cur = head;
        while(cur != null && cur.data != a) {
            cur = cur.next;
        }
        return cur;
    }

    public int removeFirst() {
        if (head == null) {              
            throw new IllegalArgumentException("Cannot remove from empty list");
        }
        Node node = head;
        head = head.next;
        node.next = null;
        return node.data;
    }

    public int removeLast() {
        if (head == null || head.next == null) {
            return removeFirst();
        }
        Node cur = head;
        while(cur.next.next != null) {
            cur = cur.next;
        }
        int data = cur.next.data;
        cur.next = null;
        return data;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        Node cur = head;
        while(cur != null) {
            sb.append(cur.data);
            if (cur.next != null) {
                sb.append(", ");
            }
            cur = cur.next;
        }
        sb.append("]");
        return sb.toString();
    }

    private Node merge(Node head1, Node head2) {
        Node dummy = new Node(0);
        Node tail = dummy;
        while (head1 != null && head2 != null) {
            if (head1.data < head2.data) {
                tail.next = head1;
                head1 = head1.next;
            } else {
                tail.next = head2;
                head2 = head2.next;
            }
            tail = tail.next;
        }
        if (head1 != null) {
            tail.next = head1;
        } else {
            tail.next = head2;
        }
        return dummy.next;
    }

    public Node mergesort(Node head) {
        if (head == null || head.next == null) {
            return head;
        }
        Node mid = findMiddle(head);
        Node right = mergesort(mid.next);
        mid.next = null;
        Node left = mergesort(head);
        return merge(left, right);
    }

    private Node findMiddle(Node head) {
        Node slow = head, fast = head.next;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }

    public static void main(String[] args) {
        List list = new List();
        list.insertAtFront(37);
        list.insertAtFront(99);
        list.insertAtFront(12);

        // the list at page 88 of the slides.
        System.out.println(list);

        list.insertAtFront(75);
        System.out.println(list);

        list.insertAtEnd(38);
        System.out.println(list);

        list.insertAfter(list.search(12), 85);
        System.out.println(list);

        list.head = list.mergesort(list.head);
        System.out.println("after sorting: " + list + "\n");

        System.out.println("delete the first, which is " + list.deleteFirst());
        System.out.println(list);

        System.out.println("delete the last, which is " + list.deleteLast());
        System.out.println(list);
    }
}

Returning -1 for failed removal is a bad idea since you are not preventing negative numbers as actual data. 为删除失败而返回-1是一个坏主意,因为您没有防止负数作为实际数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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