快速排序和两路合并排序速度_快速排序和归并排序

算法有很多种,有的是用时间换空间有的是用空间换时间,在用空间换时间的算法中,分治思想是很重要的一种算法思想,是先将一个大问题分成若干个小问题,然后逐一解决小问题,最后将小问题的解合并成原来大问题的解,其中快速排序归并排序是很典型的两种算法。

快速排序

把一个list用分治的思想分为一个大的序列和一个小的序列,然后递归的对两个子序列进行排序

步骤

  1. 选择一个基准元素,将序列分为两个子序列

  2. 对列表重新排序,将所有小于基准的元素放在基准值的前面,将所有大于基准值的元素放在基准值的后面

  3. 分别对较小元素的子序列和较大元素的子序列重复步骤1和2

function quikSort(arr){    /* 递归终止条件 */    if(arr.length<1){        return arr    }    // step 1: 获取第一个元素作为基准点,此处一定要截取,否则会陷入死循环    let pivot = arr.splice(0,1)[0];        // step 2:     let left = []  // 保存比基准小的元素    let right = [] // 保存比基准大的元素    // 对数组进行循环,并按基准对数组进行拆分    for(let i= 0;i        if(arr[i]>pivot){                right.push(arr[i])        } else {            left.push(arr[i])        }    }    // step 3: 对较大对数组和较小的数组进行递归直到不能拆分为止    return quikSort(left).concat([pivot],quikSort(right))}

浏览器运行结果,对一百万个随机数进行排序:0.609s

da96b5490762a3f2f230fee07afc6576.png

归并排序

一张图就能解释清楚什么是归并排序:

c38bf204f46da182cca6d8a28ff88782.png

不断的将数组分为两部分,直到不能拆分为止(数组只剩下一个元素),然后再把数组按大小归并到一个数组中,直到把所有元素归并起来,最后顺序也排好了
// 合并函数 function merge(left,right){    let result = []    // 循环left和right对比数组的首元素,把较小的元素放进归并数组(result)    while(left.length>0 && right.length>0){        if(left[0] < right[0]) {            result.push(left.shift())        } else {            result.push(right.shift())        }    }    // 此处的concat是为了把最后剩下的一个元素,也放进数组    return result.concat(left,right) }// 分解函数function mergeSort(arr){    if(arr.length===1){        return arr    }    // step 1:取到中间的索引,并按索引把函数分为两部分    let middleIndex = Math.floor(arr.length/2)    let left = arr.slice(0,middleIndex)    let right = arr.slice(middleIndex)    // 如果函数长度不为1,继续分解    return merge(mergeSort(left),mergeSort(right))}

浏览器运行结果,对一百万个随机数进行排序:73.548s

bd8b9958ef393242a851ae7dee903b4c.png

对比冒泡排序,浏览器运行结果,对一百万个随机数进行排序:1561.877s

function bubbleSort(arr) {    for(let i=0;i-1;i++){        /*这里要根据外层for循环的 i,逐渐减少内层 for循环的次数,          当第一次,找到最大数,放到最后,那么下一次,遍历的时候,          是不是就不能把最后一个数算上了呢?          因为他就是最大的了,不会出现,前一个数比后一个数大,          要交换位置的情况,所以内层 for 循环的次数,改成 i < arr.length - 1 -i        */         for(let j=0;j-1-i;j++){            if(arr[j]>arr[j+1]){                let temp = arr[j]                arr[j] = arr[j+1]                arr[j+1] = temp            }        }    }}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值