繁体   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);
    }
}

这是我用于合并排序的链表的代码。 但是,仅显示链接列表的后半部分。 问题是什么....?

使用Intellij:

12、99、37

75、12、99、37

75、12、99、37、38

75、12、85、99、37、38

排序后:75、85、99

删除第一个,即75

85、99

删除最后一个,即99

85

从main方法中的mergesort()获得收益的同时,您没有在此更改列表的标题。 因此,在您的情况下,列表已排序,但head仅保留75,并且根据代码工作正常

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

我重构了您的代码,请参见下文。 希望这是自我解释。

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);
    }
}

为删除失败而返回-1是一个坏主意,因为您没有防止负数作为实际数据。

暂无
暂无

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

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