[英]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.