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

    这个只不过是自己的流水账,偶尔有一些心得,错误的地方概不负责
  • 相关阅读:
    省选模拟47 题解
    省选模拟46 题解
    死磕 java集合之PriorityQueue源码分析
    拜托,面试别再问我堆(排序)了!
    死磕 java集合之ConcurrentSkipListSet源码分析——Set大汇总
    死磕 java集合之CopyOnWriteArraySet源码分析——内含巧妙设计
    死磕 java集合之TreeSet源码分析
    死磕 java集合之LinkedHashSet源码分析
    死磕 java集合之HashSet源码分析
    死磕 java集合之ConcurrentSkipListMap源码分析——发现个bug
  • 原文地址:https://www.cnblogs.com/ashitaka/p/5987929.html
Copyright © 2011-2022 走看看