zoukankan      html  css  js  c++  java
  • 快速排序之C实现和JS实现的区别

    快速排序是面试中的几乎必问的问题,理解之后发现并不难,在此贴出两种版本,与小伙伴们相互交流

    PS:今天码代码非常有感觉,所以连发三篇博客,下午打球,手感也是热的发烫,希望不忘初心,方得始终。

    进入正题,快速排序的基本思路就是的,找出数组中的某一个值,将其摆放在某一位置,比其大,放在该值的右边,比其小放在该值的左边,左右两边继续执行上述步骤,也就是递归。

    那么问题来了,C语言中如何找出数组中的某一个值的位置(以下程序均取首项),先看如下分析。

    C实现

    如图1所示,low代表数组首项,high代码数组末项,找出数组的首项 arr[len],将其储存起来(int val=arr[len]),先比较arr[high]与arr[low] 大小,,如何arr[high]>val,high左移,

    如果arr[high]>val,说明数组的顺序已调整好,否则直至arr[high]<val     arr[low]=arr[high]

    图1

    图2

    如果arr[low]<=val  将low右移,当arr[low]>val,arr[high]=arr[low] 

    图3

    如果arr[high]>=val 将high左移,arr[high]<val,arr[low]=arr[high] 

     

    图4

    如果arr[low]<=val  将low右移,当arr[low]=arr[high],则代表首项的位置找到了,为2所在位置,arr[low]=val;

    图5

    下来就简单了,对9所在位置的左右依次执行上述操作方法,也就是递归

    代码如下:

    #include <stdio.h>
    void quick_sort(int * a,int low,int high);
    int findPos(int * a,int low,int high);
    int main(){
        int i ;
        int arr[]={9,0,1,10,-5,2,13,7,11,56,33,66,77};
        //求数组的长度 
        int len=sizeof(arr)/sizeof(arr[0]);
        //排序 
        quick_sort(arr,0,len-1);
        //打印 
        for(i=0;i<len;i++){
            printf("%d ",arr[i]);
        }
            printf("
    ");
        return 0;
    }
    /*递归函数,第一个参数是数组,第二个参数是排序起始点,第三个参数是排序终止点*/
    void quick_sort(int * a,int low,int high){
        //在low小于high的时候,先找出指定值的位置,本程序指定的是a[0],  在指定值的左右继续执行找位置并赋值 
        if(low<high){
            int pos=findPos(a,low,high);
            quick_sort(a,low,pos-1);
            quick_sort(a,pos+1,high);
        }
    }
    int findPos(int * a,int low,int high){
        int val=a[low];
        while(low<high){
            //当a[high]大于val时,不用移动a[high],只需要让high左移,也就是high--,当a[high]<val,则证明该赋值了。 
            while(low<high && a[high]>=val){
                high--;
            }
            a[low]=a[high];//跳出while执行
            //当a[low]<=val,不用移动 a[low],只需要让low右移,也就是low--,当a[low]>val,则证明该赋值了。 
            while(low<high && a[low]<=val){
                low++;
            }
            a[high]=a[low];//跳出while执行
        }//跳出总的while 代表low==high,则只需要把val赋给 a[low]或 a[high] ,最终return low或high 作为递归分界线 
                a[low]=val;
                return low;
    }    

    JS实现

    js实现,也是比较容易,找出一个中间值,比其小放在左边,比其大放在右边,左右递归,有一点注意,在判断与mid[0]的大小时,循环从1开始,而不是0.

    伪代码:

    var arr=Array.length; //长度
    if(arr<=1){return arr.slice(0);}
    var left=[];//左
    var right=[];//右
    var mid=[Array[0]];//中间值
    for(var i=1;i<len;i++){
    if(Array[i]<mid[0]) left.push(Array[i])
    else right.push(Array[i]);
    }
    return left.sort.concat(mid.concat(right.sort()))//递归

    用面向对象去写,就是在数组的原型上添加一个方法,测试时去调用这个方法即可

    Array.prototype.quick_sort=function(){
            var len=this.length;
            if(len<=1){
                return this.slice(0);
            }
            var left=[];
            var right=[];
            var mid=[this[0]];
            for(var i=1;i<len;i++){
                if(this[i]<mid[0]){
                    left.push(this[i]);
                }
                if(this[i]>=mid[0]){
                    right.push(this[i]);
                }
            }
            return left.quick_sort().concat(mid.concat(right.quick_sort()));
        }
        var arr = [31, 1, -5, -6, 10, 9, 0, 14, 222];
        arr=arr.quick_sort();
        console.log(arr);

    这是测试的结果

    图6

    比较两者区别

    C实现相对于JS实现代码量能大一点,C中多了一步就是把首项的值,放到合适的位置,而JS固定好了中间值,就是第一项,比中间值小的放在中间值的左边,比中间值大的放在中间值的右边,再调用递归

    快速排序的数据结构是不确定的,时间复杂度是O(n^2), 最优时间复杂度为O(n log n),平均时间复杂度也为O(n log n),空间复杂度取决于程序的实现方法。

    这就是我对快排的理解。

  • 相关阅读:
    线程池的状态整理
    线程池 ThreadPoolExecutor 源码整理
    ReentrantReadWriteLock 源码分析
    ReentrantLock 锁释放源码分析
    编译Hadoop源码
    Ubuntu安装secureCRT
    ubuntu中为hive配置远程MYSQL database
    解决Ubuntu下sublime3无法输入中文
    Ubuntu下安装PAC Manager
    Git起步--git安装与初次运行git前配置
  • 原文地址:https://www.cnblogs.com/dirkhe/p/6793151.html
Copyright © 2011-2022 走看看