zoukankan      html  css  js  c++  java
  • 快速排序

    快速排序同归并排序一样,也采用的是分治策略。快速排序最终要的步骤是划分子数组,假设有个数组A[p..r]被划分成两个子数组(可能为空)A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每个元素都小于等于A[q],且A[q]小于等于A[q+1..r]中的每个元素。划分过程伪代码如下:

    PARTITION(A, p, r)
        x <-- A[r]
        i <-- p-1
        for j <-- p to r-1
            do if A[j] <= x
                then i <-- i+1
                    exchange A[i] <--> A[j]
        exchange A[i+1] <--> A[r]
        return i+1

    此过程的c程序如下:

    int partition(int A[], int p, int r)
    {
    	int i, j;
    	int x;
    
    	x = A[r];
    	i = p-1;
    
    	for (j = p; j < r; j++) {
    		if (A[j] <= x) {
    			swap(&A[++i], &A[j]);
    		}
    	}
    
    	swap(&A[i+1], &A[r]);
    
    	return i+1;
    }

    快速排序伪代码如下:

    QUICKSORT(A, p, r)
        if p < r
            then q <-- PARTITION(A, p, r)
                QUICKSORT(A, p, q-1)
                QUICKSORT(A, q+1, r)

    c程序如下:

    void quick_sort(int A[], int p, int r)
    {
    	int q;
    
    	if (p < r) {
    		q = partition(A, p, r);
    		quick_sort(A, p, q-1);
    		quick_sort(A, q+1, r);
    	}
    }



    例如数组{2, 8, 7, 1, 3, 5, 6, 4},排序过程是这样的:
    (1)    2 8 7 1 3 5 6 4(主元)

    (2)    2 1 3 4 7 5 6 8
    x为主元r,i为-1,j初值为0,因为A[0]为2小于x,所以i加1之后为0,然后交换A[0]和A[0]的值,因为相同所以原数组不变。i不变,j++到3,此时A[3]为1小于x,i加1之后为1,交换A[1]和A[3]的值,原数组变为2 1 7 8 3 5 6 4。j++到4,再交换A[2]和A[4]的值,交换后数组为2 1 3 8 7 5 6 4。j++,后面没有比x再小的数,所以for循环结束,再交换A[3]和A[7]的值,数组变为2 1 3 4 7 5 6 8,并返回3。

    (3)    1 2 3 4 7 5 6 8
    这样数组A被划分成了两个数组{2, 1, 3}和{7, 5, 6, 8},然后再对这两个数组进行快速排序。{2, 1, 3}数组主元为3,首先是2和2互换不变,1和1互换不变,最后3与3互换不变,这样{2, 1, 3}数组再分成两个数组{2, 1}和{3}。再对{2, 1}数组进行排序,变为{1, 2}。

    {4}    1 2 3 4 5 6 7 8
    再对数组{7, 5, 6, 8}进行排序,再分成两个数组{7, 5, 6}和{8},{7, 5, 6}数组排序之后变为{5, 6, 7}。

    最后,完整程序如下:

    #include <stdio.h>
    
    void dump(int a[], int len)
    {
    	int i;
    
    	for (i = 0; i < len; i++) {
    		printf("%3d", a[i]);
    	}
    	printf("
    ");
    }
    
    void swap(int *a, int *b)
    {
    	int tmp;
    
    	tmp = *a;
    	*a = *b;
    	*b = tmp;
    }
    
    int partition(int A[], int p, int r)
    {
    	int i, j;
    	int x;
    
    	x = A[r];
    	i = p-1;
    
    	for (j = p; j < r; j++) {
    		if (A[j] <= x) {
    			swap(&A[++i], &A[j]);
    		}
    	}
    
    	swap(&A[i+1], &A[r]);
    
    	return i+1;
    }
    
    void quick_sort(int A[], int p, int r)
    {
    	int q;
    
    	if (p < r) {
    		q = partition(A, p, r);
    		quick_sort(A, p, q-1);
    		quick_sort(A, q+1, r);
    	}
    }
    
    int main(void)
    {
    	int a[] = {2, 8, 7, 1, 3, 5, 6, 4};
    
    	int len = sizeof(a) / sizeof(a[0]);
    
    	dump(a, len);
    
    	quick_sort(a, 0, len-1);
    
    	dump(a, len);
    
    	return 0;
    }
  • 相关阅读:
    A Simple Problem with Integers poj 3468 多树状数组解决区间修改问题。
    Fliptile 开关问题 poj 3279
    Face The Right Way 一道不错的尺取法和标记法题目。 poj 3276
    Aggressive cows 二分不仅仅是查找
    Cable master(二分题 注意精度)
    B. Pasha and String
    Intervals poj 1201 差分约束系统
    UITextField的快速基本使用代码块
    将UIImage转换成圆形图片image
    color转成image对象
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3283368.html
Copyright © 2011-2022 走看看