pdqsort | 青训营笔记

216 阅读1分钟

PDQSort是一种快速的排序算法,使用简单、性能出众,被广泛应用于各种编程语言中。PDQSort的全称是"Pattern-Defeating Quicksort",也就是指在快速排序的基础上,通过一些优化手段来避免快速排序的一些缺陷,从而提高排序的效率和稳定性。

即使在最坏情况下,PDQSort也能比快速排序更加稳定,而且在处理小数组时,PDQSort有着更高的效率。PDQSort的实现原理是:通过确定一个“模式长度”,仅使用快速排序来排序长度大于模式长度的任意切片,同时使用插入排序来排序长度小于模式长度的任意切片。这种方法能够在保证排序效率的同时,避免快速排序的一些致命缺陷。

template<typename T>
void pdqsort(T\* begin, T\* end) {
const int len = end - begin;
if (len <= 1) return;

if (len == 2) {
    if (*--end < *begin) std::swap(*begin, *end);
    return;
}

T* mid = begin + len / 2;
if (*--mid < *begin) std::swap(*begin, *mid);
if (*--end < *mid) {
    std::swap(*end, *mid);
    if (*mid < *begin) std::swap(*mid, *begin);
}

T* left = begin + 1;
T* right = end - 1;
T pivot = *mid;
while (left <= right) {
    while (*left < pivot) ++left;
    while (pivot < *right) --right;
    if (left <= right) {
        std::swap(*left, *right);
        ++left;
        --right;
    }
}

T* const mid_left = left;
right = end - 1;
while (right > mid_left) {
    if (*right == pivot) {
        --right;
        continue;
    }
    T* const mid_right = right;
    --left;
    while (*left != pivot) ++left;
    if (left < mid_left) {
        right = mid_right;
        break;
    }
    std::swap(*left, *right);
}

pdqsort(begin, left);
if (pivot != *left) pdqsort(left, right + 1);
pdqsort(right + 1, end);
}

在代码中,我们首先进行了一些细致的判断,然后选择数组的中间元素作为基准值,用左右指针来移动和交换元素。同时,为了避免某些重复元素的存在,我们先对整个数组进行了一次划分,将重复的元素分到数组的两端,并用递归的方式对左右两个部分进行排序。

总的来说,PDQSort是一种优秀的排序算法,特别适用于处理小规模的数组和针对一些特定数据模式的排序问题。