Closed laizimo closed 4 years ago
继续上一篇的话题,我们来看看算法复杂度在O(n*log2n)的算法。
这篇开头我们就来分析一下最受欢迎的快速排序
快速排序,从它的名字就应该知道它很快,时间复杂度很低,性能很好。它将排序算法的时间复杂度降低到O(nlogn)
思路:
首先,我们需要找到一个基数,然后将比基数小的值放在基数的左边,将比基数大的值放在基数的右边,之后进行递归那两组已经归类好的数组。
图例:
原图片太大,放一张小图,并且附上原图片地址,有兴趣的可以看一下:
原图片地址
代码实现:
const arr = [30, 32, 6, 24, 37, 32, 45, 21, 38, 23, 47]; function quickSort(arr){ if(arr.length <= 1){ return arr; } let temp = arr[0]; const left = []; const right = []; for(var i = 1; i < arr.length; i++){ if(arr[i] > temp){ right.push(arr[i]); }else{ left.push(arr[i]); } } return quickSort(left).concat([temp], quickSort(right)); } console.log(quickSort(arr));
代码地址
性能:
归并排序,即将数组分成不同部分,然后注意排序之后,进行合并
首先,将相邻的两个数进行排序,形成n/2对,然后在每两对进行合并,不断重复,直至排序完。
//迭代版本 const arr = [3,44,38,5,47,15,36,26,27,2,46,4,19,50,48] function mergeSort(arr){ const len = arr.length; for(let seg = 1; seg < len; seg += seg){ let arrB = []; for(let start = 0; start < len; start += 2*seg){ let row = start, mid = Math.min(start+seg, len), heig = Math.min(start + 2*seg, len); let start1 = start, end1 = mid; let start2 = mid, end2 = heig; while(start1 < end1 && start2 < end2){ arr[start1] < arr[start2] ? arrB.push(arr[start1++]) : arrB.push(arr[start2++]); } while(start1 < end1){ arrB.push(arr[start1++]); } while(start2 < end2){ arrB.push(arr[start2++]); } } arr = arrB; } return arr; } console.log(mergeSort(arr));
//递归版 const arr = [3,44,38,5,47,15,36,26,27,2,46,4,19,50,48]; function mergeSort(arr, seg = 1){ const len = arr.length; if(seg > len){ return arr; } const arrB = []; for(var start = 0; start < len; start += 2*seg){ let low = start, mid = Math.min(start+seg, len), heig = Math.min(start+2*seg, len); let start1 = low, end1 = mid; let start2 = mid, end2 = heig; while(start1 < end1 && start2 < end2){ arr[start1] < arr[start2] ? arrB.push(arr[start1++]) : arrB.push(arr[start2++]); } while(start1 < end1){ arrB.push(arr[start1++]); } while(start2 < end2){ arrB.push(arr[start2++]); } } return mergeSort(arrB, seg * 2); } console.log(mergeSort(arr));
基数排序,就是将数的每一位进行一次排序,最终返回一个正常顺序的数组。
首先,比较个位的数字大小,将数组的顺序变成按个位依次递增的,之后再比较十位,再比较百位的,直至最后一位。
const arr = [3221, 1, 10, 9680, 577, 9420, 7, 5622, 4793, 2030, 3138, 82, 2599, 743, 4127, 10000]; function radixSort(arr){ let maxNum = Math.max(...arr); let dis = 0; const len = arr.length; const count = new Array(10); const tmp = new Array(len); while(maxNum >=1){ maxNum /= 10; dis++; } for(let i = 1, radix = 1; i <= dis; i++){ for(let j = 0; j < 10; j++){ count[j] = 0; } for(let j = 0; j < len; j++){ let k = parseInt(arr[j] / radix) % 10; count[k]++; } for(let j = 1; j < 10; j++){ count[j] += count[j - 1]; } for(let j = len - 1; j >= 0 ; j--){ let k = parseInt(arr[j] / radix) % 10; tmp[count[k] - 1] = arr[j]; count[k]--; } for(let j = 0; j < len; j++){ arr[j] = tmp[j]; } radix *= 10; } return arr; } console.log(radixSort(arr));
项目代码
我们一共实现了6种排序算法,对于前端开发来说,熟悉前面4种是必须的。特别是快排,基本面试必考题。本篇的内容总结分为六部分:
排序算法,是算法的基础部分,需要明白它的原理,总结下来排序可以分为比较排序和统计排序两种方式,本篇前5种均为比较排序,基数排序属于统计排序的一种。希望看完的你,能够去动手敲敲代码,理解一下
如果你对我写的有疑问,可以评论,如我写的有错误,欢迎指正。你喜欢我的博客,请给我关注Star~呦。大家一起总结一起进步。欢迎关注我的github博客
前言
继续上一篇的话题,我们来看看算法复杂度在O(n*log2n)的算法。
正文
这篇开头我们就来分析一下最受欢迎的快速排序
快速排序
快速排序,从它的名字就应该知道它很快,时间复杂度很低,性能很好。它将排序算法的时间复杂度降低到O(nlogn)
思路:
首先,我们需要找到一个基数,然后将比基数小的值放在基数的左边,将比基数大的值放在基数的右边,之后进行递归那两组已经归类好的数组。
图例:
原图片太大,放一张小图,并且附上原图片地址,有兴趣的可以看一下:
原图片地址
代码实现:
代码地址
性能:
归并排序
归并排序,即将数组分成不同部分,然后注意排序之后,进行合并
思路:
首先,将相邻的两个数进行排序,形成n/2对,然后在每两对进行合并,不断重复,直至排序完。
图例:
代码实现:
代码地址
代码地址
性能:
基数排序
基数排序,就是将数的每一位进行一次排序,最终返回一个正常顺序的数组。
思路:
首先,比较个位的数字大小,将数组的顺序变成按个位依次递增的,之后再比较十位,再比较百位的,直至最后一位。
图例:
代码实现:
项目代码
性能:
总结
我们一共实现了6种排序算法,对于前端开发来说,熟悉前面4种是必须的。特别是快排,基本面试必考题。本篇的内容总结分为六部分:
排序算法,是算法的基础部分,需要明白它的原理,总结下来排序可以分为比较排序和统计排序两种方式,本篇前5种均为比较排序,基数排序属于统计排序的一种。希望看完的你,能够去动手敲敲代码,理解一下