单链表上的快速排序

发布于 2024-10-28 10:49:17 字数 1056 浏览 2 评论 0原文

我的快速排序不起作用。我特别不确定要传递给分区算法的内容以及如何管理枢轴,因为在一种情况下它成为头节点,在另一种情况下成为最后一个节点。我的方法基于数​​组的解决方案。这是我的尝试。有什么想法吗?请注意,选择分区算法是为了适应单链表 (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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

忆悲凉 2024-11-04 10:49:17

链表上快速排序的正常方法是在分区步骤中创建两个(或更好三个,中间的所有元素都等于主元元素)新列表,对第一个和最后一个递归排序,然后将它们连接在一起。

相反,您的代码会交换节点内的数据......有趣。我用以下(子)列表尝试了它:

        first                            last
        [ 5 ]-->[ 3 ]-->[ 7 ]-->[ 9 ]-->[ 2 ]

看看这里你的算法做了什么:

        [ 5 ]-->[ 3 ]-->[ 7 ]-->[ 9 ]-->[ 2 ]
          p
                 ptr

3<5? (yes) {
pivot=5
        [ 3 ]-->[ 3 ]-->[ 7 ]-->[ 9 ]-->[ 2 ]
          p      ptr
        [ 3 ]-->[ 7 ]-->[ 7 ]-->[ 9 ]-->[ 2 ]
          p      ptr
        [ 3 ]-->[ 7 ]-->[ 5 ]-->[ 9 ]-->[ 2 ]
          p      ptr
        [ 3 ]-->[ 7 ]-->[ 5 ]-->[ 9 ]-->[ 2 ]
                  p
                 ptr
}
        [ 3 ]-->[ 7 ]-->[ 5 ]-->[ 9 ]-->[ 2 ]
                  p
                         ptr

这是第一次迭代后的状态。由于 ptr != null,我们现在进入下一次迭代,但我认为您已经可以在这里看到问题了。在下一次迭代之后,它看起来像这样:

        [ 3 ]-->[ 5 ]-->[ 9 ]-->[ 7 ]-->[ 2 ]
                          p
                                 ptr

在下一次迭代中不会发生交换:

        [ 3 ]-->[ 5 ]-->[ 9 ]-->[ 7 ]-->[ 2 ]
                          p
                                         ptr

现在我们将得到一个 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:

        first                            last
        [ 5 ]-->[ 3 ]-->[ 7 ]-->[ 9 ]-->[ 2 ]

Look here what your algorithm does:

        [ 5 ]-->[ 3 ]-->[ 7 ]-->[ 9 ]-->[ 2 ]
          p
                 ptr

3<5? (yes) {
pivot=5
        [ 3 ]-->[ 3 ]-->[ 7 ]-->[ 9 ]-->[ 2 ]
          p      ptr
        [ 3 ]-->[ 7 ]-->[ 7 ]-->[ 9 ]-->[ 2 ]
          p      ptr
        [ 3 ]-->[ 7 ]-->[ 5 ]-->[ 9 ]-->[ 2 ]
          p      ptr
        [ 3 ]-->[ 7 ]-->[ 5 ]-->[ 9 ]-->[ 2 ]
                  p
                 ptr
}
        [ 3 ]-->[ 7 ]-->[ 5 ]-->[ 9 ]-->[ 2 ]
                  p
                         ptr

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:

        [ 3 ]-->[ 5 ]-->[ 9 ]-->[ 7 ]-->[ 2 ]
                          p
                                 ptr

In the next iteration no swaps happen:

        [ 3 ]-->[ 5 ]-->[ 9 ]-->[ 7 ]-->[ 2 ]
                          p
                                         ptr

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:

  • In the swapping step, you should make sure that afterwards p points to the node which now contains the pivot element.
  • you should stop when reaching the last element, and make sure you don't swap after it (but that still the element itself is swapped if necessary).
旧时浪漫 2024-11-04 10:49:17
//logic - from left to right, remove smaller node and append at the beginning,
public void partition(int x)// x is your pivot element.
        {
            Node prev = null;
            Node cur = root;
            while (cur!=null)
            {
                if ( cur.data > x || cur == root)
                {
                    cur = cur.next;
                    prev = cur;
                }
                else
                {
                    Node next = cur.next;
                    if (prev != null) prev.next = next;
                    cur.next = root;
                    root = cur;
                    cur = next;
                }
            }
        }
//logic - from left to right, remove smaller node and append at the beginning,
public void partition(int x)// x is your pivot element.
        {
            Node prev = null;
            Node cur = root;
            while (cur!=null)
            {
                if ( cur.data > x || cur == root)
                {
                    cur = cur.next;
                    prev = cur;
                }
                else
                {
                    Node next = cur.next;
                    if (prev != null) prev.next = next;
                    cur.next = root;
                    root = cur;
                    cur = next;
                }
            }
        }
裸钻 2024-11-04 10:49:17

您可能想查看“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.

行至春深 2024-11-04 10:49:17

对于非破坏性版本,请将以下伪代码翻译为 Java:

quickSort list
    | list.isEmpty = empty list
    | otherwise = concat (quickSort lower) (new List(pivot, quickSort upper))
    where
         pivot = list.head
         lower = list of elements from list.tail that are < pivot
         upper = list of elements from list.tail that are >= pivot

For a non-destructive version translate the following pseudocode into Java:

quickSort list
    | list.isEmpty = empty list
    | otherwise = concat (quickSort lower) (new List(pivot, quickSort upper))
    where
         pivot = list.head
         lower = list of elements from list.tail that are < pivot
         upper = list of elements from list.tail that are >= pivot
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文