我正在阅读 Robert Sedwick 算法和数据结构第 1-4 部分的书中的快速排序算法。
template <class item>
static void quicksort(item [] a, int l, int r)
{
if(r <= l) return;
int i = partition(a,l,r);
quicksort(a, l, i-1);
quicksort(a, i+1, r);
}
template <class item>
int partition(item a[], int l, int r)
{
int i = l-1; j = r; item v = a[r];
for(;;) {
while( a[++i] < v );
while( v < a[--j] )
if( j == l )
break;
if( i >= j)
break; // pointer crossing.
exch(a[i], a[j]);
}
exch(a[i], a[r]);
return i;
}
书中有关于上述算法的以下文字。
当文件中存在重复键时,指针交叉很微妙。我们可以通过在 i < j 时终止扫描,然后使用 j 而不是 i-1 来为第一次递归调用分隔左子文件的右端来稍微改进分区过程。在这种情况下让循环再迭代一次是一种改进,因为当扫描循环以 j 终止并且 i 指代同一个元素时,我们最终会在它们的最终位置有两个元素:停止两次扫描的元素,因此,它必须等于分隔元素和分隔元素本身。这种改变可能是值得做的,因为在这种特殊情况下,程序留下的记录的键等于 a[r] 中的分区键,
我的问题是
- 我们如何修改上面的程序,下面有描述?我很难修改它以理解文本。
- 如果存在更多重复键,为什么上述快速排序算法无法有效工作。
- 如果存在更多重复键,上述修改将如何改进?
- 作者的意思是“他在调用快速排序(a,i + 1,r)中的第一个分区退化,因为它最右边的键是它的最小键。” ? 作者这里的退化是什么意思?
感谢您的时间和帮助。