常用算法探微~快速排序

算法是编程的灵魂,可见其重要,开发者,无论学什么语言,都必须掌握常见的算法。今天,笔者就和大家分享下,对常见算法~快速排序法的理解,它是冒泡排序的一种该进。基本思想是:通过一遍排序将排序的数据划分为两个部分,使其中一部分,比另一部分数据小,然后再分别对这两部份数据继续进行这种排序,按此规则继续,知道每个部分为空,或者只含有一个数,整个快速排序结束。

算法描述

1)从数列中挑出一个元素,称该元素为基准。

2)扫描一遍数列,将所有比基准小的元素,排在基准前面,所有比基准大的元素排在基准后面

3)通过递归,将各个子序列划分为更小的序列,直到把小于基准值的子数列和大于基准的元素的子数列排序。

下面以一组代排序数列演示快速排序的过程,假设有8个需要排序的数据序列如下:

69,65,90,37,92,6,28,54

不妨设数组A存这八个数,其排序过程如下:

1、在变量left中保存数组最小的序号0,在变量right中存数组最大的序号7,在变量base中保存数组最后元素A【0】

2、从数组右侧开始,逐步取出元素与base比较,知道找到,比base小的数据为止

3、将右侧与基准小的数存到A【left】

4、从数组左侧开始逐步取出元素与base比较,知道找打比base大的数据为止,

5、将左侧比基准大的数保存A【right】

6、将base中保存的值保存到A【left】中,经过这些运算,得到上述第二个图,经过这次分割,base左侧即left所指向的数据,比base小,右侧比之大

7、接下来,通过递归调用,将left左侧数据进行同样的排序,,再将left右侧数据进行同样的排序

这样便可以完成排序操作,伪代码如下:

void 快速排序(数组,左侧序号,右侧序号)
{
      分割数组,将left保存到 i
      快速排序(数组,原左侧序号,i-1)
      快速排序(数组,i+1,原右侧序号)
}
C语言描述:

void QuickSort(int a[],int left,int right)
{
	int i,j;
	if(left<right)
	{
		i=Division(a,left,right);//Division 为分割函数。
		QuickSort(a,left,i);;
		QuickSort(a,i+1,right);
	}
}
其中分割数组函数实现:

int Division(int a[],int left,int right)        
{
	int base=a[left];								//取左侧元素为基准元素
	while(left<right)								//左侧序号小于右侧序号
	{
		while (left<right && a[right]>base)			//从右向左寻找第一个比基准小的元素
			--right;								
		a[left]=a[right];							//将比基准小的元素移到左侧
		while (left<right && a[left]<base)			//从左向右寻找第一个比基准大的数字
			++left;								
		a[right]=a[left];							//将比基准大的移到右侧
	}
	a[left]=base;									//保存基准数
	return left;									//返回基准序号

完整源代码如下:

#include <stdio.h>
#include <stdlib.h>
#define ARRAYLEN 10
int CreateData(int arr[],int n,int min,int max) //创建一个随机数组,a保存生成的数据,n为数组元素的数量 
{
    int i,j,flag;
    srand(time(NULL));
    if((max-min+1)<n) return 0; //最大数与最小数之差小于产生数组的数量,生成数据不成功 
    for(i=0;i<n;i++)
    {
        do
        {
            arr[i]=(max-min+1)*rand()/(RAND_MAX+1)+min;
            flag=0;
            for(j=0;j<i;j++)
            {
                if(arr[i]==arr[j])
                    flag=1;
            }
        }while(flag);        
    }
    return 1;
}
int Division(int a[],int left, int right) //分割 
{
    int base=a[left];    //基准元素
    while(left<right)
    {
        while(left<right && a[right]>base)
            --right;     //从右向左找第一个比基准小的元素
        a[left]=a[right];
        while(left<right && a[left]<base )
            ++left;      //从左向右找第一个比基准大的元素
        a[right]=a[left];
    }
    a[left]=base;
    return left;
}
void QuickSort(int a[],int left,int right)
{
    int i,j;
    if(left<right)
    {
        i=Division(a,left,right);   //分割
        QuickSort(a,left,i-1);     //将两部分分别排序
        QuickSort(a,i+1,right);
    }
}
int main()
{
    int i,a[ARRAYLEN];
    for(i=0;i<ARRAYLEN;i++)
        a[i]=0;
    if(!CreateData(a,ARRAYLEN,1,100))
    {
        printf("生成随机数不成功!
");
        getch();
        return 1;
    }
    printf("原数据:"); 
    for(i=0;i<ARRAYLEN;i++)
        printf("%d ",a[i]);
    printf("
");
    QuickSort(a,0,ARRAYLEN-1);
    printf("排序后:"); 
    for(i=0;i<ARRAYLEN;i++)
        printf("%d ",a[i]);
    printf("
");
    getch();
    return 0;   
}

运行截图:




原文地址:https://www.cnblogs.com/jiahao89/p/5118303.html