冒泡排序
算法描述
「冒泡排序」相信对于很多同学来说并不陌生,它应该是我们最经典的算法了,无论学什么语言,都能见到它的身影。「基本思想」:重复遍历要排序的数组,每次比较两个元素的大小,如果顺序错误就交换两个元素的顺序。遍历数组重复进行比较直到排序完成。
算法实现
「基本步骤」
- 比较相邻的两个元素。如果第一个比第二个大,则交换位置;
- 对每一对相邻元素重复第一个步骤,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
- 针对所有的元素重复以上的步骤,除了最后一个;
- 重复步骤1~3,直到排序完成。
「代码实现」
/**
* 外循环控制需要比较的元素,比如第一次排序后,
最后一个元素就不需要比较了,内循环则负责两两元素比较,将元素放到正确位置上_
*/
function bubbleSort(arr) {
const len = arr.length
for(let i=0; i for(let j=0;j // 注意边界值 if(arr[j] > arr[j+1]){ [arr[j],arr[j+1]] = [arr[j+1],arr[j]] // 交换位置 } } } return arr } console.log(bubbleSort([3,44,15,36,26,27,2,46,4,19,50,48])) //[2,3,4,15,19,26,27,36,44,46,48,50]
「时间复杂度:O(n^2)」
快速排序
算法描述 「快速排序」,是一种对冒泡排序改进的算法,它是处理大数据最快的排序算法之一了。「基本思想:」它是一种分而治之的算法,找出一个参考值,通过递归的方式将
【关注尚硅谷,轻松学IT】数据依次分解为包含较小元素和较大元素的不同子序列。该算法不断重复这个步骤直至所有数据都是有序的。
算法实现
「基本步骤」
「代码实现」 function quickSort(arr) { if(arr.length<=1) return arr const left = [],right = [],current = arr.splice(0,1) for(let i=0; i if(arr[i] // 小于参考值放左边 left.push(arr[i]) }else{ // 否则放右边 right.push(arr[i]) } } //递归上述步骤 return quickSort(left).concat(current,quickSort(right)) } console.log(quickSort([3,44,15,36,26,27,2,46,4,19,50,48])) //[2, 3, 4, 15, 19, 26, 27, 36, 44, 46, 48, 50]
「时间复杂度:O(nlogn)」
插入排序
算法描述 「插入排序」是一种简单直观的排序算法。「基本思想:」通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
算法实现
「基本步骤」
「代码实现」 /**双层循环,外循环控制未排序的元素,内循环控制已排序的元素,将未排序元素设为标杆, 与已排序的元素进行比较,小于则交换位置,大于则位置不动 */ function insertSort(arr) { let tem for(let i=0; i tem = arr[i] for(let j=i; j>=0; j--){ if(arr[j-1] > tem){ arr[j] = arr[j-1] }else { arr[j] = tem break } } } return arr } console.log(insertSort([3,44,15,36,26,27,2,46,4,19,50,48])) //[2, 3, 4, 15, 19, 26, 27, 36, 44, 46, 48, 50]
「时间复杂度O(n^2)」
选择排序
算法描述 「选择排序」是一种简单直观的排序算法,「基本思想:」首先在待排序序列中选出最小或最大值,存放在排序序列起始位置,然后再从剩余未排序元素中继续寻找最小或最大元素,放到已排序序列末尾。以此类推,直到所有元素均排序完毕。
算法实现
「基本步骤」
「代码实现」 /** * 先假设第一个元素为最小的,然后通过循环找出最小元素, * 然后同第一个元素交换,接着假设第二个元素,重复上述操作即可 */ function selectSort(arr) { let len = arr.length, minIndex, tem for(let i=0; i minIndex = i //最小值下标 for(let j=i+1; j if(arr[j] < arr[minIndex]){ // 找出最小值 minIndex = j //更换最小值下标 } } // 交换位置 tem = arr[i] arr[i] = arr[minIndex] arr[minIndex] = tem } return arr } console.log(selectSort([3,44,15,36,26,27,2,46,4,19,50,48])) //[2, 3, 4, 15, 19, 26, 27, 36, 44, 46, 48, 50]
「时间复杂度O(n^2)」
归并排序
算法描述 「归并排序」是一种借助“归并”进行排序的方法,归并的含义是将两个或两个以上的有序序列归并成一个有序序列的过程。「基本思想:」将若干有序序列逐步归并,最终归并为一个有序序列。和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间_
。
算法实现
「基本步骤」
「代码实现」 // 将数组一直等分,然后合并 function merge(left, right) { let tem = [] while(left.length && right.length) { if(left[0] < right[0]) { tem.push(left.shift()) }else{ tem.push(right.shift()) } } return tem.concat(left,right) } function mergeSort(arr) { const len = arr.length if(len<2) return arr let mid = Math.floor(len / 2), left = arr.slice(0,mid), right = arr.slice(mid) return merge(mergeSort(left),mergeSort(right)) } console.log(mergeSort([3,44,15,36,26,27,2,46,4,19,50,48])) // [2, 3, 4, 15, 19, 26, 27, 36, 44, 46, 48, 50]
「时间复杂度O(nlogn)」
希尔排序
算法描述 「希尔排序」是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。「基本思想:」是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
算法实现
「基本步骤」
「代码实现」 function shellSort(arr) { var len = arr.length; for(var gap = Math.floor(len / 2); gap > 0; gap = Math.floor(gap / 2)) { for(var i = gap; i < len;i++) { var j = i; var current = arr[i]; while (j - gap >= 0 && current < arr[j - gap]) { arr[j] = arr[j - gap]; j = j - gap; } arr[j] = current; } } return arr; } console.log(shellSort([50,70,60,80,61,84,83,88,87,99])) //[50, 60, 61, 70, 80, 83, 84, 87, 88, 99]
「时间复杂度:O(nlogn)」
计数排序
算法描述 「计数排序」是一种稳定的排序算法。「基本思想:」使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C来将A中的元素排到正确的位置。它只能对整数进行排序。
算法实现
「基本步骤」
「代码实现」 function countingSort(arr) { let len = arr.length, b = [], c = [], min = max = arr[0] for(let i=0; i min = min <= arr[i] ? min : arr[i] max = max >= arr[i] ? max : arr[i] c[arr[i]] = c[arr[i]] ? c[arr[i]] + 1 : 1 // 计数 } for(let i=min; i< max; i++) { c[i+1] = (c[i+1] || 0) + (c[i] || 0) } for(let i=len-1; i>=0; i--) { b[c[arr[i]] - 1] = arr[i] c[arr[i]]-- } return b } console.log(countingSort([2,3,8,7,1,2,2,2,7,3,9,8,2,1,4])) //[ 1, 1, 2, 2, 2, 2, 2, 3, 3, 4, 7, 7, 8, 8, 9]
「时间复杂度:O(n+k)」 k表示输入的元素是n 个0到k之间的整数
基数排序
算法描述 「基数排序」也是非比较的排序算法,「基本思想:」按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,
【关注尚硅谷,轻松学IT】再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以是稳定的。
算法实现
「基本步骤」
「代码实现」 function radixSort(arr, maxDigit) { let counter = [], mod = 10, dev = 1; for (let i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) { for(let j = 0; j < arr.length; j++) { let bucket = parseInt((arr[j] % mod) / dev) if(counter[bucket]==null) { counter[bucket] = [] } counter[bucket].push(arr[j]) } let pos = 0 for(let j = 0; j < counter.length; j++) { let value = null if(counter[j]!=null) { while ((value = counter[j].shift()) != null) { arr[pos++] = value } } } } return arr; } console.log(radixSort([3,44,15,36,26,27,2,46,4,19,50,48],2)) // [ 2, 3, 4, 15, 19, 26, 27, 36, 44, 46, 48, 50]
「时间复杂度:O(n*k)」 k表示输入的元素是n 个0到k之间的整数
文章来源于前端南玖
总结