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);