美文网首页
不积跬步之快速排序

不积跬步之快速排序

作者: 雨飞飞雨 | 来源:发表于2021-05-26 23:28 被阅读0次

快速排序使用了分治思想来实现。

和冒泡排序一样,快速排序也属于交换排序,通过元素直接的比较和交换位置来达到排序的目的。
不同的是,冒泡排序在每一轮中只把一个元素冒泡到数列的一端,而快速排序则是:每一轮挑选一个基准元素。并让其他比它大的元素移动到数列一边,比它小的元素移动到数列的另一边。从而把数列拆解成两个部分。

这种思路就是分治疗法。

具体实现上则又分两种:
1.双边循环法
2.单边循环法

双边循环法

/**
 * 快速排序
 * */

function quickSort(array,startIndex,endIndex){
        //递归结束条件:startIndex大于或等于endIndex
        if(startIndex >= endIndex){
                return ;
        }
        
        //得到基准元素位置
        let pivotIndex = partition(array,startIndex,endIndex);
        //左边的循环
        quickSort(array,startIndex,pivotIndex -1);
        //右边循环
        quickSort(array,pivotIndex+1,endIndex);
}

function partition(array,startIndex,endIndex){
        //取第一个位置或者随机位置的元素作为基准元素。
        let pivot = array[startIndex];
        let left = startIndex;
        let right = endIndex;
        
        while (left !== right){
                //和我们的基准线相比较,如果大于基准线,就向左移动,直到截止
                while (left < right && array[right] > pivot){
                        right --;
                        console.log("right==",right)
                }
                
                //控制left指针向右移动,也就是和基准线比较,如果小基准线就继续向右移动,直到碰到大于的或者是
                while (left < right && array[left] <= pivot){
                         left++;
                        console.log("left==",left)
        
                }
                
                //交换left和right指针所指向的元素,也就是位置互换
                if(left < right){
                        let p = array[left];
                        array[left] = array[right];
                        array[right] = p;
                }
        }
        
        //基准线和指针重合点交换
        array[startIndex] = array[left];
        array[left] = pivot;
        return left;
}

单边循环法

双边循环法是从数组的两边交替遍历元素,虽然直观,却比较繁琐。而单边循环法则简单很多。

只从数组的一边对元素进行遍历和交换。

[4,7,3,5,6,2,8,1]

开始和双边循环法相似,首先要选定基准元素pivot,同时设置一个mark指针指向数列的起始位置。这个mark指针代表小于基准元素的区域边界。

pivot=4;
mark=0;

接下来从基准元素的下一个位置开始遍历。
如果遍历到元素大于基准 元素的,就继续往后遍历。

如果遍历到的元素小于基准元素,则需要做两件事儿。
第一:把mark指针右移一位,因为小于pivot的区域边界增大了1;
第二:让最新遍历到的元素和mark指针所在的位置的元素交换位置,因为最新遍历的元素归属于小于pivot的区域。

好,上代码:

//单边循环法

function quickSort(array,startIndex,endIndex){
        //递归结束条件:startIndex大于或等于endIndex
        if(startIndex >= endIndex){
                return ;
        }
        
        //得到基准元素位置
        let pivotIndex = partition(array,startIndex,endIndex);
        //左边的循环
        quickSort(array,startIndex,pivotIndex -1);
        //右边循环
        quickSort(array,pivotIndex+1,endIndex);
}

//单边循环法
function partition(array,startIndex,endIndex){
        
        let pivot = array[startIndex];
        let mark = startIndex;
        
        for(let i = startIndex+1;i<=endIndex;i++){
                if(array[i] < pivot){
                        mark++;
                        let p = array[mark];
                        array[mark] = array[i];
                        array[i] = p;
                }
        }
        array[startIndex] = array[mark];
        array[mark] = pivot;
        return mark;
}

over...

相关文章

  • 不积跬步之快速排序

    快速排序使用了分治思想来实现。 和冒泡排序一样,快速排序也属于交换排序,通过元素直接的比较和交换位置来达到排序的目...

  • 不积跬步之选择排序

    选择排序 假如我们有一组歌的数据,我们需要按照播放量从大往小排序。最简单的做法就是,先从这组数据里找到最大的那个,...

  • 不积跬步之冒泡排序及优化

    冒泡排序 一句话描述:相邻的两个元素相比较,大的那个移动到右侧,然后进行数组长度-1轮后,就排好序了。 冒泡排序的...

  • 不积跬步之鸡尾酒排序

    鸡尾酒排序是从冒泡排序又优化升级而来。比如如下场景: 如果使用冒泡排序,因为只需要移动1这一个位置,却需要轮回8次...

  • 不积跬步之计数排序

    之前的排序都是通过比较来完成的,例如冒泡排序和快速排序。 两个值比较,如果大的值,就交换。 而计数排序则是利用里字...

  • 不积跬步

    2018/10/25 星期四 晴 没想到二姐的高价小收音机比手机的辐射要强,放在床边睡觉,...

  • 不积跬步

    “不积跬步无以至千里”常用来激励。 可在自己身上发掘这句名言,却只有垃圾、肥肉和慢。 一个上午,断断续续收拾了两个...

  • 不积跬步

    生活中看起不起眼的事情,对一些人来说就是财富机遇 朋友在我们单位上班,也属于从别的单位挖过来的,老板慧眼识珠,两人...

  • 点滴积累成就精彩演讲

    冰冻三尺,非一日之寒。 ——王充不积跬步,无以...

  • 晨间日记

    不登高山,不知天之高也; 不临深溪,不知地之厚也。 不积跬步,无以至千里; 不积小流,无以成江海。 ​​​

网友评论

      本文标题:不积跬步之快速排序

      本文链接:https://www.haomeiwen.com/subject/zvolsltx.html