使用优先队列对链表进行排序
Sort linked list using priority queue
public class SortList{
class ListNode{
ListNode next;
int val;
public ListNode(int val){
this.val = val;
}
}
public static ListNode sortList(ListNode head) {
if(head == null)
return null;
PriorityQueue<ListNode> pq = new PriorityQueue<ListNode>( (a,b) -> (a.val - b.val));
while(head != null){
pq.add(head);
head = head.next;
}
ListNode pointer = pq.poll();
ListNode result = pointer;
while(pq.size() >0 ){
System.out.println(pq.size());
ListNode nextTemp = pq.poll();
pointer.next = nextTemp;
pointer = pointer.next;
}
return result;
}
public static void main(String[] args){
ListNode head = new ListNode(3);
ListNode n2 = new ListNode(2);
ListNode n3 = new ListNode(5);
ListNode n4 = new ListNode(9);
ListNode n5 = new ListNode(7);
ListNode n6 = new ListNode(4);
head.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = n6;
n6.next = null;
ListNode result = sortList(head);
while(result != null){
System.out.println(result.val);
result = result.next;
}
}
}
我想使用优先级队列对链表进行排序,但为什么在 poll() 直到队列为空时出现无限循环?列表大小减少但增加,优先级队列永远不会变空。
输出:
6
5
4
3
2
1
1
2
3
4
6
7
9
2
3
4
6
7
9
2
3
4
6
7
9
2
3
4
6
7
9
2
3
4
6
.........无限循环
让我们看看您的输出:
6
5
4
3
2
1 Up to this point, you're removing items from the priority queue
1 This is the first item in the sorted list output
2
3
4
6
7
9 End of the sorted list output
2 ?? This happens because 9 is pointing to 2 in the original list.
3
4
6
7
9
从您的输出中可以清楚地看出,您 运行 的代码与您发布的代码不同。我知道这是因为输出不包含值“5”,并且输出中有 7 个不同的项目,但代码中只有 6 个。
您的无限循环不在优先队列中。您可以通过修改 main()
来证明这一点,以便它在开始写入列表时输出一条消息,如下所示:
ListNode result = sortList(head);
System.out.println("Sorted list is:"); // start output
while(result != null){
System.out.println(result.val);
result = result.next;
}
正如我在评论中指出的那样,问题在于优先级队列中的最后一项具有非空 next
指针。所以当你删除它并将它添加到你的结果列表时,你最终会遇到一个循环。结果列表最终如下所示:
1 -> 2 -> 3 -> 4 -> 6 -> 7 -> 9 ->
^ \
\ /
<-----<---------<--------<-
要解决此问题,请修改您的 sortList
方法,以便将列表中最后一项的 next
指针设置为 null
:
while(pq.size() >0 ){
System.out.println(pq.size());
ListNode nextTemp = pq.poll();
pointer.next = nextTemp;
pointer = pointer.next;
}
pointer.next = null; // terminate the list!!
return result;
这种错误很容易用调试器诊断出来。您可以单步执行代码以 确切地 查看它在做什么,并且您可以设置断点以便代码在特定行停止执行。如果您一直在使用调试器,您可能会在几分钟内发现这个问题。如果您不知道如何使用它,请学习。现在.
诊断这些问题的另一种方法是放置输出语句,如我所示。一个简单的 System.out.println("Finished the sort.");
会告诉您排序实际上已经完成,问题是稍后出现的。这是我们在拥有源代码级调试器之前使用的技术,今天对于调试服务、网页和其他在调试器中 运行 不方便的程序来说仍然非常方便。
public class SortList{
class ListNode{
ListNode next;
int val;
public ListNode(int val){
this.val = val;
}
}
public static ListNode sortList(ListNode head) {
if(head == null)
return null;
PriorityQueue<ListNode> pq = new PriorityQueue<ListNode>( (a,b) -> (a.val - b.val));
while(head != null){
pq.add(head);
head = head.next;
}
ListNode pointer = pq.poll();
ListNode result = pointer;
while(pq.size() >0 ){
System.out.println(pq.size());
ListNode nextTemp = pq.poll();
pointer.next = nextTemp;
pointer = pointer.next;
}
return result;
}
public static void main(String[] args){
ListNode head = new ListNode(3);
ListNode n2 = new ListNode(2);
ListNode n3 = new ListNode(5);
ListNode n4 = new ListNode(9);
ListNode n5 = new ListNode(7);
ListNode n6 = new ListNode(4);
head.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = n6;
n6.next = null;
ListNode result = sortList(head);
while(result != null){
System.out.println(result.val);
result = result.next;
}
}
}
我想使用优先级队列对链表进行排序,但为什么在 poll() 直到队列为空时出现无限循环?列表大小减少但增加,优先级队列永远不会变空。
输出:
6
5
4
3
2
1
1
2
3
4
6
7
9
2
3
4
6
7
9
2
3
4
6
7
9
2
3
4
6
7
9
2
3
4
6
.........无限循环
让我们看看您的输出:
6
5
4
3
2
1 Up to this point, you're removing items from the priority queue
1 This is the first item in the sorted list output
2
3
4
6
7
9 End of the sorted list output
2 ?? This happens because 9 is pointing to 2 in the original list.
3
4
6
7
9
从您的输出中可以清楚地看出,您 运行 的代码与您发布的代码不同。我知道这是因为输出不包含值“5”,并且输出中有 7 个不同的项目,但代码中只有 6 个。
您的无限循环不在优先队列中。您可以通过修改 main()
来证明这一点,以便它在开始写入列表时输出一条消息,如下所示:
ListNode result = sortList(head);
System.out.println("Sorted list is:"); // start output
while(result != null){
System.out.println(result.val);
result = result.next;
}
正如我在评论中指出的那样,问题在于优先级队列中的最后一项具有非空 next
指针。所以当你删除它并将它添加到你的结果列表时,你最终会遇到一个循环。结果列表最终如下所示:
1 -> 2 -> 3 -> 4 -> 6 -> 7 -> 9 ->
^ \
\ /
<-----<---------<--------<-
要解决此问题,请修改您的 sortList
方法,以便将列表中最后一项的 next
指针设置为 null
:
while(pq.size() >0 ){
System.out.println(pq.size());
ListNode nextTemp = pq.poll();
pointer.next = nextTemp;
pointer = pointer.next;
}
pointer.next = null; // terminate the list!!
return result;
这种错误很容易用调试器诊断出来。您可以单步执行代码以 确切地 查看它在做什么,并且您可以设置断点以便代码在特定行停止执行。如果您一直在使用调试器,您可能会在几分钟内发现这个问题。如果您不知道如何使用它,请学习。现在.
诊断这些问题的另一种方法是放置输出语句,如我所示。一个简单的 System.out.println("Finished the sort.");
会告诉您排序实际上已经完成,问题是稍后出现的。这是我们在拥有源代码级调试器之前使用的技术,今天对于调试服务、网页和其他在调试器中 运行 不方便的程序来说仍然非常方便。