快速排序的C语言实现

来源:互联网 发布:matlab2016b mac 编辑:程序博客网 时间:2024/06/02 05:09

快速排序主要过程如下:
分解:数组A[p..r]被划分为两个(可能为空的)子数列A[p..q-1]和A[q+1..r],使得A[p..q-1]中元素都小于等于A[q],A[q+1..r]中元素都大于A[q]。
解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进行排序。
合并:因为子数组都是原址排序,所以不需要合并,数组A[p..r]已经有序。
非随机化版本的快速排序实现如下:

int partition(int *source, int head, int tail) {    int x = source[tail];    int i = head - 1, j = head;    for (j = head; j < tail; j++) {        if (source[j] <= x) {            i++;            swap(source + j, source + i);        }    }    swap(source + tail, source + i + 1);    return i + 1;}void quick_sort(int *source, int head, int tail) {    if (head >= tail)        return;    int mid = partition(source, head, tail);    quick_sort(source, head, mid - 1);    quick_sort(source, mid + 1, tail);}

注意,对于一个几乎有序的排列,插入排序的性能往往要优于快速排序。由逆序对内容可知,插入排序的运行时间为O(n+d),其中d为逆序对的数目。又由于一个几乎有序的数列中,逆序对的数目很少,因此插入排序的运行时间接近线性。而上述非随机的快速排序在该种情况下极易产生空的划分,所以在该种情况下,插入排序的性能往往优于快速排序。
随机化版本实现如下:

int randomized_partition(int *source, int head, int tail) {    swap(source + rand() % (tail - head + 1) + head, source + tail);    int x = source[tail];    int i = head - 1, j = head;    for (j = head; j < tail; j++) {        if (source[j] <= x) {            i++;            swap(source + j, source + i);        }    }    swap(source + tail, source + i + 1);    return i + 1;}void randomized_quick_sort(int *source, int head, int tail) {    if (head >= tail)        return;    int mid = randomized_partition(source, head, tail);    randomized_quick_sort(source, head, mid - 1);    randomized_quick_sort(source, mid + 1, tail);}

在划分前,随机选取一个元素于尾部将作为主元的元素交换,再进行划分。