快速排序

来源:互联网 发布:数据库的导入和导出 编辑:程序博客网 时间:2024/06/06 00:22

快速排序

原理:

快速排序作为最经典的排序算法之一,一直深受各大面试公司和研究生入学考试的青睐。作为一中不稳定的、In-place排序,快排有着其不可逾越的高效性,其排序效率在同等O(n*lgN)的几种排序中最高。

该算法的基本思想如下:

  1. 从数组中选取一个基数,作为参照。

  2. 接下来我们的目标就是在数组中为这个基数找到一个适当的位置,使得位于基数前的数字均小于基数,位于基数后的数字均大于基数。(具体方法见下)

  3. 然后分别对基数左侧和右侧的数组分别进行步骤2的推到过程,直到每个数组只有一个数。

从上面的推导中可以看出,快速排序是基于分治思想的,通过逐步缩小排序范围,来将大问题分解为小问题。接下来我们主要介绍步骤2的具体实施过程。

假设我们有如下数组 a:

0 1 2 3 4 5 6 7 8 62 34 89 50 108 76 48 64 57

首先,我们选取第一个元素作为基数 base(改进版的快速排序可以通过随机选取基数达到改进算法的目的),这里我们默认使用第一个元素,即a[0] 。此时,相当于从数组中将a[0]抠出来了,数组如下:

0(i) 1 2 3 4 5 6 7 8(j) 34 89 50 108 76 48 64 57

然后,记住我们的目标是在数组中为基数base找到一个有序的位置,把比base大的数丢到其右边,比base小的数丢到其左边。

做一些初始化的工作, i=0,j=8, 此时 base = 62

1) 从 j 开始,从右向左遍历数组,找到一个比 base 小的数。

如果 a[j]>=base,则 j– 。直到 j=6,符合条件,将 a[j] 丢到空白处,即。此时 a[i] = a[j],第 j 个元素右侧的元素均大于 base,第 i 个元素左侧的元素均小于 base。

0 1(i) 2 3 4 5 6(j) 7 8 48 34 89 50 108 76 64 57

2) 从 i 开始,从左向右遍历数组,找到一个比 base 小的数。

如果 a[i]<=base,则 i++ 。直到 i=2 ,符合条件,将 a[i] 丢到空白处,即 a[j] = a[i] ,j– 。此时,第 j 个元素右侧的元素均大于 base,第 i 个元素左侧的元素均小于 base。

0 1 2 (i) 3 4 5(j) 6 7 8 48 34 50 108 76 89 64 57

3) 重复1)、2)的过程,先从后向前找,再从前向后找,直到 i >= j, a[i] = base 。

0 1 2 3 (i)(j) 4 5 6 7 8 48 34 50 108 76 89 64 57

此时,i >=j , a[i] = base

0 1 2 3 (i)(j) 4 5 6 7 8 48 34 50 62 108 76 89 64 57

最后,分别对区间[0,2]和[4,8]重复1)、2)、3)的过程。

代码:

#include<iostream>#define MAX 100using namespace std;/*输出数组arr,如果flag为0,则升序输出;否则,逆序输出。arr:数组n:数组长度flag:输出标志*/void Output(int arr[],int n,int flag){    int i;    if(flag == 0)    {        for(i=0;i<n;i++)        {            if(i!= n-1)            {                cout<<arr[i]<<" ";            }            else{                cout<<arr[i]<<endl;            }        }    }    else    {        for(i=n-1;i>=0;i--)        {            if(i!= 0)            {                cout<<arr[i]<<" ";            }            else{                cout<<arr[i]<<endl;            }        }    }}/*快速排序arr:待排序数组s:待排序区间左端点n:待排序区间右端点*/void QuickSort(int arr[],int s,int n){    if(s >= n)    {        return;    }    int i=s,j=n;    int base = arr[i];//基数    while(i != j)    {        while(arr[j] >= base && i != j)//对右侧排序        {            j--;        }        if(i != j)        {            arr[i] = arr[j];            i++;            while(arr[i] <= base && i!= j)//对左侧排序            {                i++;            }            if(i != j)            {                arr[j] = arr[i];                j--;            }        }    }    arr[i] = base;    QuickSort(arr,s,i-1);//对base左侧排序    QuickSort(arr,i+1,n);//对base右侧排序}int main(void){    int i,n,flag;    int arr[MAX];    cin>>n;//输入元素个数    for(i=0;i<n;i++)    {        cin>>arr[i];    }    cin>>flag;//输入输出标志。如果flag为0,则升序输出;否则,逆序输出。    QuickSort(arr,0,n-1);    Output(arr,n,flag);    return 0;}
1 0
原创粉丝点击