回温js算法
---恢复内容开始---
一,冒泡排序。
具体算法描述如下:
<1>.比较相邻的元素。如果第一个比第二个大,就交换它们两个;
<2>.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
<3>.针对所有的元素重复以上的步骤,除了最后一个;
<4>.重复步骤1~3,直到排序完成。
代码实现
let arr = [9, 10, 8, 7, 5, 4, 2, 1, 3, 6]; function sort(arr) { var as = [].concat(arr), len = arr.length, count = 0; for (let i = 0; i < len-1; i++) { for (let j = 0; j < len-1-i; j++) { if(as[j]>as[j+1]){ var item = as[j]; as[j] = as[j+1]; as[j+1] = item; count++; } } } console.log(count) return as } console.log(sort(arr))
结果:
count:37
arr:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
二,选择排序。
描述:
在时间复杂度上表现最稳定的排序算法之一,因为无论什么数据进去都是O(n²)的时间复杂度。。。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。
实现:
let arr = [9, 10, 8, 7, 5, 4, 2, 1, 3, 6]; function sort(arr) { var as = [].concat(arr), len = arr.length, count = 0, minNum, item; for (let i = 0; i < len-1; i++) { minNum = i; for (let j = i+1; j < len; j++) { if(as[minNum] > as[j]){ minNum = j; count++ } } item = as[i]; as[i] = as[minNum]; as[minNum] = item; } console.log(count) return as } console.log(sort(arr))
三,插入排序。
描述:插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
实现:
let arr = [9, 10, 8, 7, 5, 4, 2, 1, 3, 6]; function sort(arr) { var as = [].concat(arr), len = arr.length, count = 0, preIndex, item; for (let i = 1; i < len; i++) { preIndex = i-1; item = as[i]; while(preIndex >= 0 && as[preIndex] > item){ as[preIndex+1] = as[preIndex] preIndex-- ; count++; } as[preIndex+1] = item } console.log(count) return as } console.log(sort(arr))
四,希尔排序。
描述:希尔排序本质上是一种插入排序,但是对数列进行了等间隔分组处理,在每一组中做插入排序,这一优化使得原本 O(n^2) 的时间复杂度一下降为 O(nlogn)
实现:
let arr = [9, 10, 8, 7, 5, 4, 2, 1, 3, 6]; function shellsort(arr) { for (let gap = Math.floor(arr.length/2); gap > 0; gap = Math.floor(gap/2)) { for (let i = gap; i < arr.length; i++) { let item = arr[i]; let j = i-1; while (j>=0 && arr[j] > item) { arr[j+1] = arr[j]; j--; } arr[j+1] = item; } } } console.log(shellsort(arr));
五,归并排序。
let arr = [9, 10, 8, 7, 5, 4, 2, 1, 3, 6]; function mergeSort(arr) { if (arr.length<2) { return arr } let middle =parseInt(arr.length/2); let left = arr.slice(0,middle); let right = arr.slice(middle); if(left.length =='undefined' && right.length == 'undefined'){ return false } return merge(mergeSort(left),mergeSort(right)) } function merge(left,right) { let result= []; while (left.length && right.length) { if(left[0]<= right[0]){ result.push(left.shift()) }else{ result.push(right.shift()) } } while (left.length) { result.push(left.shift()) } while (right.length) { result.push(right.shift()) } return result } console.log(mergeSort(arr));
六,快速排序。
let arr = [9, 10, 8, 7, 5, 4, 2, 1, 3, 6]; function quickSort(arr) { if(arr.length<=1){ return arr } let middle = Math.floor(arr.length/2); let povid = arr.splice(middle,1)[0]; let left = []; let right = []; for (let i = 0; i < arr.length; i++) { if(arr[i] < povid){ left.push(arr[i]) }else { right.push(arr[i]) } } return quickSort(left).concat([povid],quickSort(right)) } console.log(quickSort(arr))
七,堆排序。
//调整函数 function headAdjust(elements, pos, len){ //将当前节点值进行保存 var swap = elements[pos]; //定位到当前节点的左边的子节点 var child = pos * 2 + 1; //递归,直至没有子节点为止 while(child < len){ //如果当前节点有右边的子节点,并且右子节点较大的场合,采用右子节点 //和当前节点进行比较 if(child + 1 < len && elements[child] < elements[child + 1]){ child += 1; } //比较当前节点和最大的子节点,小于则进行值交换,交换后将当前节点定位 //于子节点上 if(elements[pos] < elements[child]){ elements[pos] = elements[child]; pos = child; child = pos * 2 + 1; } else{ break; } elements[pos] = swap; } } //构建堆 function buildHeap(elements){ //从最后一个拥有子节点的节点开始,将该节点连同其子节点进行比较, //将最大的数交换与该节点,交换后,再依次向前节点进行相同交换处理, //直至构建出大顶堆(升序为大顶,降序为小顶) for(var i=elements.length/2; i>=0; i--){ headAdjust(elements, i, elements.length); } } function sort(elements){ //构建堆 buildHeap(elements); //从数列的尾部开始进行调整 for(var i=elements.length-1; i>0; i--){ //堆顶永远是最大元素,故,将堆顶和尾部元素交换,将 //最大元素保存于尾部,并且不参与后面的调整 var swap = elements[i]; elements[i] = elements[0]; elements[0] = swap; //进行调整,将最大)元素调整至堆顶 headAdjust(elements, 0, i); } } var elements = [3, 1, 5, 7, 2, 4, 9, 6, 10, 8]; sort(elements); console.log(elements);
八,计数排序。
function countingSort(array) { let len = array.length,B = [],C = [],min = array[0], max = array[0]; for (var i = 0; i < len; i++) { min = min <= array[i] ? min : array[i]; max = max >= array[i] ? max : array[i]; C[array[i]] = C[array[i]] ? C[array[i]] + 1 : 1; } // 计算排序后的元素下标 for (var j = min; j < max; j++) { C[j + 1] = (C[j + 1] || 0) + (C[j] || 0); } for (var k = len - 1; k >= 0; k--) { B[C[array[k]] - 1] = array[k]; C[array[k]]--; } return B; } var elements = [3, 1, 5, 7, 2, 4, 9, 6, 10, 8]; console.log(countingSort(elements));
九,桶排序。
// @param array 数组 // @param num 桶的数量 function bucketSort(array, num) { if (array.length <= 1) { return array; } var len = array.length, buckets = [], result = [], min =array[0], max =array[0] , space, n = 0; var index = Math.floor(len / num) ; while(index<2){ num--; index = Math.floor(len / num) ; } for (var i = 1; i < len; i++) { min = min <= array[i] ? min : array[i]; max = max >= array[i] ? max : array[i]; } space = (max - min + 1) / num; //步长 for (var j = 0; j < len; j++) { var index = Math.floor((array[j] - min) / space); if (buckets[index]) { // 非空桶,插入排序 var k = buckets[index].length - 1; while (k >= 0 && buckets[index][k] > array[j]) { buckets[index][k + 1] = buckets[index][k]; k--; } buckets[index][k + 1] = array[j]; } else { //空桶,初始化 buckets[index] = []; buckets[index].push(array[j]); } } while (n < num) { result = result.concat(buckets[n]); n++; } return result; } var elements = [3, 1, 5, 7, 2, 4, 9, 6, 10, 8]; console.log(bucketSort(elements,4));
十,基数排序。
/** * 基数排序适用于: * (1)数据范围较小,建议在小于1000 * (2)每个数值都要大于等于0 * @author damonare * @param arr 待排序数组 * @param maxDigit 最大位数 */ //LSD Radix Sort function radixSort(arr, maxDigit) { var mod = 10; var dev = 1; var counter = []; console.time('基数排序耗时'); for (var i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) { for(var j = 0; j < arr.length; j++) { var bucket = parseInt((arr[j] % mod) / dev); if(counter[bucket]== null) { counter[bucket] = []; } counter[bucket].push(arr[j]); } var pos = 0; for(var j = 0; j < counter.length; j++) { var value = null; if(counter[j]!=null) { while ((value = counter[j].shift()) != null) { arr[pos++] = value; } } } } console.timeEnd('基数排序耗时'); return arr; } var elements = [3, 1, 5, 7, 2, 4, 9, 6, 10, 8]; console.log(radixSort(elements,2));