Java 单链表上递归快速排序的基本情况
我正试图在单链表上进行递归快速排序。基本情况是什么?当我到达它时,为了让函数“倒带”并打印排序列表,我需要做什么?这里有一些代码,但我认为它是非常错误的Java 单链表上递归快速排序的基本情况,java,algorithm,list,recursion,quicksort,Java,Algorithm,List,Recursion,Quicksort,我正试图在单链表上进行递归快速排序。基本情况是什么?当我到达它时,为了让函数“倒带”并打印排序列表,我需要做什么?这里有一些代码,但我认为它是非常错误的 public static void qSort(SLLNode first, SLLNode last) { SLLNode pivot = first ; SLLNode head = pivot.succ ; if (first!=last) { while (head!=null)
public static void qSort(SLLNode first, SLLNode last)
{
SLLNode pivot = first ;
SLLNode head = pivot.succ ;
if (first!=last)
{
while (head!=null)
{
if (head.data.compareToIgnoreCase(pivot.data)<0)
{
pivot.succ = head.succ ;
head.succ = first ;
first = head ;
qSort(first, pivot) ;
qSort(head, last) ;
}
qSort(first, pivot) ;
qSort(head, last) ;
}
}
}
基本大小写是一个包含0或1个元素的列表。您不需要“倒带”。当您进行递归调用时,它会在调用完成后返回递归堆栈
if(first==last)返回代码>一般情况下
对于快速排序的一般回顾,您可能应该回顾。简言之,如果您使用分区
帮助函数将列表置于一种状态,即小于轴心点的所有内容都在列表的左侧,大于轴心点的所有内容都在列表的右侧,则会更容易。然后使用轴的两侧递归调用quick sort
EJP也有一个很好的观点。我还没有在链表上看到快速排序
不管怎样,我们还是去做吧
在我看来,使用链表进行快速排序的算法类似于
def qsort(head, tail)
if head == tail
return
pivot = tail
current = head
while current != pivot
if current.value < pivot.value
move/prepend current to head of the list
else
move/append current to tail of the list
current = current.next
qsort(head, pivot-1)
qsort(pivot, tail)
这是我们的开始
SLLNode pivot = first ;
SLLNode head = pivot.succ ;
给我们
A->B->C->D
F H L
P
让我们从概念上说if(head.data.compareToIgnoreCase(pivot.data),请注意,在first==last
的基本情况下,您有一个包含一个元素的链表,因此它已经被排序
我认为你的算法可能有点不对劲。你需要一个循环,将小于轴心的所有内容移动到上半部分,将大于轴心的所有内容移动到下半部分。然后(循环完成后!)你可以递归地对这些内容进行排序。我看到你的方法有点不同,但我不相信这是正确的
最后,正如其他人所说,对链表进行排序不是一项非常有用的任务。你不会用自行车牵引拖车……研究链表的快速排序是一件有用的事情。在研究任何算法时,了解绝对需要的是什么是很重要的
在本例中,我们发现不需要随机访问迭代器。实际上,前向迭代器就足够了。
斯捷潘诺夫在STL方面的很多工作就是提取这些信息
这是C++中的一个简单实现,很抱歉语言的改变。
我只是交换数据而不是节点指针。执行节点指针与快速排序无关
是的,我知道我选择的枢轴元素可能会导致问题。
可以找到第一个和最后一个之间的距离d,然后在[0,d]范围内选择一个随机数x。现在将初始化为第一个x的指针向前移动一次,并将其数据与第一个指向的数据交换
struct Node
{
Node(int d) : data(d), next(0) {}
~Node() { delete next; }
Node* next;
int data;
};
void Quicksort(Node* first, Node* last)
{
if (first == last)
{
return;
}
Node* pivot = first;
Node* boundary = first;
for (Node* it = first->next; it != last; it = it->next)
{
// Invariant:
// The iterators in the range [first, boundary->next)
// point to nodes with data less than the pivot
// element's.
// The iterators in the range [boundary->next, it)
// point to nodes with data greater or equal to
// the pivot element's.
if (it->data < pivot->data)
{
// Swap the data to maintain the invariant
boundary = boundary->next;
std::swap(it->data, boundary->data);
}
}
// Put the pivot data in its right place
std::swap(pivot->data, boundary->data);
Quicksort(first, boundary);
Quicksort(boundary->next, last);
}
可能您需要检查列表为空的基本情况,以便在(first==last | | first==null)时变为ifreturn;
@Baba是的,我有点说错了。更新了我的答案,希望更有用。是的,我知道数组版本。更简单。我尝试了数组中的分区,但它似乎更复杂。最终我想到了直接递归,我觉得我现在已经很接近了。缺少experience@Baba更新了更多的分析。我希望这会有帮助,而且我做对了:)
A->B->C->D
F H L
P
pivot.succ = head.succ ;
A->C->D B->C
F L H
P
head.succ = first ;
B->A->C->D
H F L
P
first = head ;
B->A->C->D
H P L
F
A->B->C->D
F H L
P
B->A->C->D
H P L
F
qSort(head, last);
qSort(pivot, last);
struct Node
{
Node(int d) : data(d), next(0) {}
~Node() { delete next; }
Node* next;
int data;
};
void Quicksort(Node* first, Node* last)
{
if (first == last)
{
return;
}
Node* pivot = first;
Node* boundary = first;
for (Node* it = first->next; it != last; it = it->next)
{
// Invariant:
// The iterators in the range [first, boundary->next)
// point to nodes with data less than the pivot
// element's.
// The iterators in the range [boundary->next, it)
// point to nodes with data greater or equal to
// the pivot element's.
if (it->data < pivot->data)
{
// Swap the data to maintain the invariant
boundary = boundary->next;
std::swap(it->data, boundary->data);
}
}
// Put the pivot data in its right place
std::swap(pivot->data, boundary->data);
Quicksort(first, boundary);
Quicksort(boundary->next, last);
}
Quicksort(head, 0);