zoukankan      html  css  js  c++  java
  • 常用算法探微~快速排序

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

    算法描述

    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;   
    }
    

    运行截图:




  • 相关阅读:
    《C++标准程序库》 第6章 STL Container
    《C++语言99个常见编程错误》
    单例模式
    《C++标准程序库》 第7章 Iterator Adapters
    Shell颜色封装(C++)
    《改善C++程序的150个建议》
    OpenCV之图片的创建、保存和复制
    XMLDOM对象方法:对象事件
    三国中最精辟的十句话
    中国十大名茶及鉴别方法
  • 原文地址:https://www.cnblogs.com/jiahao89/p/5118303.html
Copyright © 2011-2022 走看看