在排序
之后,稳定排序会讨论相同的键没有越过对方在数组索引8处考虑重复键4
& 9,按以下顺序,
a
= [5 20 19 18 17 8 4 4 4 ]其中pivot
= 0,i
= 1,j
= 9分区逻辑说,
i
指针从左向右移动。只要i
值≤a[i]
,就移动a[pivot]
。swap(a[i], a[j])
j
指针从右向左移动。只要j
值≥≥a[j]
,就移动a[pivot]
。swap(a[i], a[j])
按照此程序两次,
a
= [5 4 19 18 17 8 4 5 4 20]在i
= 1&j
= 9。
a
= [5 4 19 18 17 8 4 5 4 20]停留在i
= 2&j
= 8
a
= [5 4 4 18 17 8 4 5 19 20]在i
= 2&j
= 8
我的理解是,由于重复键4
在两次交换后丢失了订单,因此快速排序不是稳定排序。
问题:
根据我的理解,这是快速排序不稳定的原因吗?如果是,我们是否有任何替代分区方法来维护上述示例中的密钥4
的顺序?
答案 0 :(得分:1)
Quicksort 本身的定义中没有任何内容可以使其稳定或不稳定。它可以是。
Quicksort在数组上最常见的实现涉及通过一对指针之间的交换进行分区,一个指针从头到尾进行,另一个从头到尾进行。这确实产生了一个不稳定的Quicksort。
虽然这种分区方法肯定很常见,但不要求算法成为Quicksort。在将Quicksort应用于数组时,这只是一种简单而常见的方法。
另一方面,考虑在单链表上进行快速排序。在这种情况下,您通常通过创建两个单独的链接列表来进行分区,一个包含小于枢轴值的链接列表,另一个包含大于枢轴值的链接列表。因为你总是从头到尾遍历列表(没有很多其他合理的选择与单链表)。只要将每个元素添加到子列表的 end ,您创建的子列表就会按原始顺序包含相同的键。因此,结果是稳定的排序。另一方面,如果您不关心稳定性,可以将元素拼接到子列表的开头(稍微容易做到复杂度不变)。在这种情况下,排序将(再次)不稳定。
分区链表的实际机制非常简单,只要你不太喜欢选择分区。
node *list1 = dummy_node1;
node *add1 = list1;
node *list2 = dummy_node2;
node *add2 = list2;
T pivot = input->data; // easiest pivot value to choose
for (node *current = input; current != nullptr; current = current->next)
if (current->data < pivot) {
add1->next = current;
add1 = add1 -> next;
}
else {
add2->next = current;
add2 = add2->next;
}
add1->next = nullptr;
add2->next = nullptr;