zoukankan      html  css  js  c++  java
  • 快速排序,C语言实现

      排序法里比较出名的,具体的算法看下图:

    这篇博客说的通俗易懂:http://blog.csdn.net/morewindows/article/details/6684558

    这是快速排序的基础,用代码实现如下:

    void DiviedSort(int* arr_p,int start,int end)
    {
        int left,right,i=0;
        int pivot,result;
        bool flag;
        flag = TRUE;
        pivot = arr_p[start];
        right = end;
        left = start;
        #if DEBUG
        printf("pivot:%d
    ",pivot);
        printf("L: ");
        for(i=0;i<end+1;i++){
            if(i==0)
                printf("_ ");
            else
                printf("%d ",arr_p[i]);
        }
        printf("
    ");
        #endif
        while(left<right && flag){
            while(arr_p[right]>=pivot){
                 right--;
                if(right<=left){ //右边没有找到小于pivot的数 退出总循环
                    arr_p[left] = pivot; //将pivot保存到左边的坑里
                    flag = FALSE;
                    break;
                }
            }
            if(flag){
                //找到小于pivot的数移动到left
                arr_p[left] = arr_p[right];
                arr_p[right] = 1000;
                left++;
                if(left>=right){
                    flag = FALSE;
                    arr_p[right] = pivot;//当left右移等于right说明正好结束;
                }
            }else{
                #if DEBUG
                printf("Lf: ");
                for(i=0;i<end+1;i++){
                    if(arr_p[i]==1000)
                        printf("_ ");
                    else
                        printf("%d ",arr_p[i]);
                }
                printf("
    ");
                #endif
                break;
            }
            #if DEBUG
            printf("R: ");
            for(i=0;i<end+1;i++){
                if(arr_p[i]==1000)
                    printf("_ ");
                else
                    printf("%d ",arr_p[i]);
            }
            printf("
    ");
            #endif
            while(arr_p[left]<=pivot){
                left++;
                if(left>=right){//左边没有找到大于pivot的数退出总循环
                    arr_p[right] = pivot;//保存pivot到右边的坑里
                    flag = FALSE;
                    break;
                }
            }
            if(flag){
                //找到大于pivot的数移动到right
                arr_p[right] = arr_p[left];
                arr_p[left] = 1000;
                right--;
                if(right<=left){
                    flag = FALSE;
                    arr_p[left] = pivot;//当right左移等于left说明正好结束
                }
            }else{
                #if DEBUG
                printf("Rf: ");
                for(i=0;i<end+1;i++){
                    if(arr_p[i]==1000)
                        printf("_ ");
                    else
                        printf("%d ",arr_p[i]);
                }
                printf("
    ");
                #endif
                break;
            }
            #if DEBUG
            printf("L: ");
            for(i=0;i<end+1;i++){
                if(arr_p[i]==1000)
                    printf("_ ");
                else
                    printf("%d ",arr_p[i]);
            }
            printf("
    ");
            #endif
        }
    }
    View Code

    运行结果是:

    这个例子比较特殊。一轮就得出结果了,但是实际上要对pivot左右两边都分别递归调用这个算法,才能得到从小到大的顺序。

    这里递归判断的条件是:

    Left<Right

    左边下标大于或者等于右边下标的时候说明数字已经按照从小到大排列。

    下面是快速排序的完整代码。

    //快速排序
    //left:数组的起始位
    //right:数组的结束位置,注意不是数组的最大容量
    void QuickSort(int * arr,int left,int right)
    {
        int pivotNum = 0;
        int start,end;
        if(left<right){
            start = left,end = right;
            pivotNum = arr[start];
            while(start<end){
                //从右边找一个小于pivotNum的数
                while(start<end && arr[end]>=pivotNum){
                    end--;//右边的游标左移
                }
                if(start<end){
                    arr[start++] = arr[end];
                }
                //从左边找一个大于pivotNum的数
                while(start<end && arr[start]<=pivotNum){
                    start++;//左边的游标右移
                }
                if(start<end){
                    arr[end--] = arr[start];
                }
            }    
            arr[start] = pivotNum;//这里在得出按照pivotNum比较得出顺序之后,要把中间数保存到最后游标停下的位置
            QuickSort(arr,left,start-1);
            QuickSort(arr,start+1,right);
        }
    }

    验证代码:

    int main(int argc, char *argv[]) {
        int i=0;
        int arr[11] = {6,2,3,9,1,2,7,41,4,1,0};
        QuickSort(arr,0,10);
        for(i=0;i<11;i++){
            printf("%d ",arr[i]);
        }
        printf("
    ");
        system("pause");
        return 0;
    }

    运行结果:

    最后对于pivotNum中间值的选择可以随机选择也可以去中间值。

     快速排序的效率问题:

    如果每次确定的中值都是最小或者最大,那么时间复杂度是O(N^2);

    最好的情况是中值正好是中间值,那么时间复杂度是O(nlgN);

    总结:就平均效率而言,快速排序是基于关键之比较的速度最快的,平均效率是O(nlgN);
     

    这个只不过是自己的流水账,偶尔有一些心得,错误的地方概不负责
  • 相关阅读:
    微人事项目-mybatis-持久层
    通过外键连接多个表
    springioc
    Redis 消息中间件 ServiceStack.Redis 轻量级
    深度数据对接 链接服务器 数据传输
    sqlserver 抓取所有执行语句 SQL语句分析 死锁 抓取
    sqlserver 索引优化 CPU占用过高 执行分析 服务器检查
    sql server 远程备份 bak 删除
    冒泡排序
    多线程 异步 beginInvoke EndInvoke 使用
  • 原文地址:https://www.cnblogs.com/ashitaka/p/5987929.html
Copyright © 2011-2022 走看看