单链表上的快速排序
我的快速排序不起作用。我特别不确定要传递给分区算法的内容以及如何管理枢轴,因为在一种情况下它成为头节点,在另一种情况下成为最后一个节点。我的方法基于数组的解决方案。这是我的尝试。有什么想法吗?请注意,选择分区算法是为了适应单链表 (SLL) 的单向性质。
public static SLL quickSort(SLL list, SLLNode first, SLLNode last)
{
if (first != null && last != null)
{
SLLNode p = partition(list, first, last) ;
quickSort(list,first,p) ;
quickSort(list,p.succ, last) ;
}
return list ;
}
public static SLLNode partition(SLL list, SLLNode first, SLLNode last)
{
//last.succ = null ;
SLLNode p = first ;
SLLNode ptr = p.succ ;
while (ptr!=null)
{
if (ptr.data.compareToIgnoreCase(p.data)<0)
{
String pivot = p.data ;
p.data = ptr.data ;
ptr.data = p.succ.data ;
p.succ.data = pivot ;
p = p.succ ;
}
ptr = ptr.succ ;
}
return p ;
}
[编辑]
我想“就地”执行此操作
我正在寻求有关如何管理的帮助此过程中的头部和最后一个。
除非我的方法不可能,否则请不要建议替代方案
My quickSort doesn't work. I'm particularly unsure about what to pass through to the partition algorithm and how to manage the pivot as in one case it becomes a header node and in the other case a last node. I based my approach on the solution for arrays. Here's my attempt. Any ideas? Please note that the partioning algorithm was chosen to suit the one-directional nature of a singly-linked list(SLL).
public static SLL quickSort(SLL list, SLLNode first, SLLNode last)
{
if (first != null && last != null)
{
SLLNode p = partition(list, first, last) ;
quickSort(list,first,p) ;
quickSort(list,p.succ, last) ;
}
return list ;
}
public static SLLNode partition(SLL list, SLLNode first, SLLNode last)
{
//last.succ = null ;
SLLNode p = first ;
SLLNode ptr = p.succ ;
while (ptr!=null)
{
if (ptr.data.compareToIgnoreCase(p.data)<0)
{
String pivot = p.data ;
p.data = ptr.data ;
ptr.data = p.succ.data ;
p.succ.data = pivot ;
p = p.succ ;
}
ptr = ptr.succ ;
}
return p ;
}
[EDIT]
I want to do this 'in-place'
I am looking for help specifically on how to manage head and last in this process.
Please don't suggest alternatives unless my approach is imposible
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
链表上快速排序的正常方法是在分区步骤中创建两个(或更好三个,中间的所有元素都等于主元元素)新列表,对第一个和最后一个递归排序,然后将它们连接在一起。
相反,您的代码会交换节点内的数据......有趣。我用以下(子)列表尝试了它:
看看这里你的算法做了什么:
这是第一次迭代后的状态。由于
ptr != null
,我们现在进入下一次迭代,但我认为您已经可以在这里看到问题了。在下一次迭代之后,它看起来像这样:在下一次迭代中不会发生交换:
现在我们将得到一个 NullPointerException,因为
ptr.next == null
(或者如果这是一个更大列表的子列表) ,我们会在限制之外进行交换)。因此,一些想法:
p
指向现在包含枢轴元素的节点。last
元素时停止,并确保不在它之后进行交换(但如果需要,元素本身仍然会被交换)。The normal approach for a quicksort on linked lists would be to create two (or better three, the middle one being all elements equal to the pivot element) new lists in the partitioning step, sort the first and last recursively, and then concatenate them together.
Your code instead swaps the data inside the nodes ... interesting. I tried it with the following (sub)list:
Look here what your algorithm does:
This is the state after the first iteration. Since
ptr != null
, we now go in the next iteration, but I think you can already here see the problem. After the next iteration it looks like this:In the next iteration no swaps happen:
And now we will get a NullPointerException, since
ptr.next == null
(or if this is a sublist of a bigger list, we would swap outside of the limits).So, some ideas:
p
points to the node which now contains the pivot element.last
element, and make sure you don't swap after it (but that still the element itself is swapped if necessary).您可能想查看“last.succ = null”行。我认为您可能需要找到其他方法来检查是否已到达要分区的列表段的末尾。事实上,我认为你应该得到一个空指针异常,但我可能是错的。
You might want to check out the line "last.succ = null". I think that you might want to find some other way to check if you've reached the end of the list segment you're partitioning. As it is, I think you should be getting a null-pointer exception, but I could be mistaken.
对于非破坏性版本,请将以下伪代码翻译为 Java:
For a non-destructive version translate the following pseudocode into Java: