所以我一直在尝试使用合并排序对链接列表进行排序,我发现这个代码并尝试使用它,但它看起来没有真正起作用?
它可能有什么问题?我不太确定getMiddle方法,虽然我知道它应该获得列表的中间值,以便从列表本身处理2个列表
这是代码;
public Node mergeSort(Node head) {
if (head == null || head.link == null) {
return head;
}
Node middle = getMiddle(head);
Node sHalf = middle.link;
middle.link = null;
return merge(mergeSort(head), mergeSort(sHalf));
}
public Node merge(Node a, Node b) {
Node dummyHead;
Node current;
dummyHead = new Node();
current = dummyHead;
while (a != null && b != null) {
if ((int) a.getData() <= (int) b.getData()) {
current.link = a;
a.link = a;
}
else {
current.link = b;
b.link = a;
}
current = current.link;
}
current.link = (a == null) ? b : a;
return dummyHead;
}
public Node getMiddle(Node head) {
if (head == null) {
return head;
}
Node slow, fast;
slow = fast = head;
while (fast.link != null && fast.link.link != null) {
slow = slow.link;
fast = fast.link.link;
}
return slow;
}
主要方法:
Object data;
MyLinkedList list = new MyLinkedList(); //empty list.
for (int i = 0; i < 3; i++) { //filling the list
data = console.nextInt();
list.insertAtFront(data);
}
System.out.print("Print(1): ");
list.printList();
list.mergeSort(list.getHead());
System.out.print("List after sorting: ");
list.printList();
答案 0 :(得分:1)
一个问题是getMiddle
方法无法正确返回中间Node
。
考虑一个包含5个节点的链表(a,b,c,d,e)
head
,slow
和fast
都从索引0(a)开始。
while
循环的第一次迭代后,slow
位于1(b),fast
位于2(c);在第二次迭代之后,slow
处于2(c)并且快于4(e)。这些都不是空的,所以发生另一次迭代,将缓慢放在3(d)和快null
。由于fast
为null,因此退出while
循环并返回slow
;但是slow
有节点3(d)而不是中间节点2(c)。
获取中间节点的另一种方法是简单地使用节点数:
public Node getMiddle(Node head) {
Node counter = head;
int numNodes = 0;
while(counter != null) {
counter = counter.link;
numNodes++;
}
if(numNodes == 0)
return null;
Node middle = head;
for(int i=0; i<numNodes/2; i++)
middle = middle.link;
return middle;
}
我的mergeSort
方法很好,但从技术上讲,如果head
为head.link
,则只需要返回null
,而head
本身就是null
1}}(因为这无论如何都不会发生):
public Node mergeSort(Node head) {
if (head.link == null) {
return head;
}
// same
}
最重要的是,您的merge
方法。您可以在public void setData(Object)
课程中编写Node
方法,以简化此操作。以下代码应该可行,但我不能说它是最好/最有效的工作方式
public Node merge(Node a, Node b) {
Node combined = new Node();
Node current = combined;
while(a != null || b != null) {
if(a == null)
addNode(current, b);
if(b == null)
addNode(current, a);
if((int)a.getData()<(int)b.getData())
addNode(current, a);
else
addNode(current, b);
}
return combined;
}
使用以下辅助方法:
public void addNode(Node n1, Node n2) {
n1.setData((int)n2.getData());
n1.link = new Node();
n1 = n1.link;
n2 = n2.link
}