// 冒泡排序(BubbleSort) O(n2) const BubbleSort = (arr = []) => { const startTime = new Date().getTime(); if (!Array.isArray(arr)) return false; const tmpArr = arr.slice(0); let changeFlag = false; for (let i=0; i<tmpArr.length-1; i++) { for(let j=tmpArr.length-1;j>0;j--) { if (tmpArr[j-1]>tmpArr[j]) { [tmpArr[j-1],tmpArr[j]]=[tmpArr[j],tmpArr[j-1]]; changeFlag = true; } } if (!changeFlag) break; // 优化排序实现 } const endTime = new Date().getTime(); return [tmpArr, endTime-startTime]; }
// 改进冒泡排序(BubbleSort) O(n2/2) const BubbleSort2 = (arr = []) => { const startTime = new Date().getTime(); if (!Array.isArray(arr)) return false; const tmpArr = arr.slice(0); let changeFlag = false; for (let i=0; i<tmpArr.length-1; i++) { for(let j=tmpArr.length-1;j>i;j--) { if (tmpArr[j-1]>tmpArr[j]) { [tmpArr[j-1],tmpArr[j]]=[tmpArr[j],tmpArr[j-1]]; changeFlag = true; } } if (!changeFlag) break; // 优化排序实现 } const endTime = new Date().getTime(); return [tmpArr, endTime-startTime]; }
// 选择排序(SelctionSort) // 普通实现 const SelctionSort = (arr = []) => { const startTime = new Date().getTime(); if (!Array.isArray(arr)) return false; const tmpArr = arr.slice(0); for (let i=0; i<tmpArr.length; i++) { let minIndex = i; for(let j=i+1;j<tmpArr.length;j++) { if (tmpArr[minIndex]>tmpArr[j]) { minIndex = j; } } if (minIndex !==i) { [tmpArr[i],tmpArr[minIndex]]=[tmpArr[minIndex], tmpArr[i]]; } } const endTime = new Date().getTime(); return [tmpArr, endTime-startTime]; } // 优化选择排序 const SelctionSort2 = (arr=[]) => { const startTime = new Date().getTime(); if (!Array.isArray(arr)) return false; const tmpArr = arr.slice(0); const len = tmpArr.length; //最小值下标 let minIndex = 0; //最大值下标 let maxIndex = 0; let left = 0; let right = len - 1; let j = 0; while (left<right) { maxIndex = left; minIndex = left; for (j = left; j <= right; j++) { if (tmpArr[j]>tmpArr[maxIndex]) { maxIndex = j; } if (tmpArr[j] < tmpArr[minIndex]) { minIndex = j; } } //将最大值插到最后 if (maxIndex != right) { [tmpArr[maxIndex],tmpArr[right]]=[tmpArr[right],tmpArr[maxIndex]]; // swap(tmpArr[maxIndex], tmpArr[right]); } //防止minpos在最大值要插入的位置 if (minIndex == right) { minIndex = maxIndex; } //将最小值插到最前面 if (minIndex != left) { [tmpArr[left],tmpArr[minIndex]]=[tmpArr[minIndex],tmpArr[left]]; // swap(tmpArr[minIndex], tmpArr[left]); } left++; right--; } const endTime = new Date().getTime(); return [endTime-startTime]; }
// 插入排序(Insertion Sort) const InsertionSort = (arr=[]) => { const startTime = new Date().getTime(); if (!Array.isArray(arr)) return false; const tmpArr = arr.slice(0); for (let i=0; i<tmpArr.length; i++) { for (let j=i+1;j>0;j--) { if (tmpArr[j-1]>tmpArr[j]) { [tmpArr[j-1],tmpArr[j]]=[tmpArr[j],tmpArr[j-1]]; } else { break; // 优化插入排序 } } } const endTime = new Date().getTime(); return [tmpArr, endTime-startTime]; }
// 快速排序(Quicksort) const Quicksort = (arr=[]) => { const startTime = new Date().getTime(); if (!Array.isArray(arr)) return false; const tmpArr = arr.slice(0); let result; const quickSort_ = (arr=[]) => { if (arr.length <= 1) { return arr; } const pivotIndex = Math.floor(arr.length/2); const pivot = arr.splice(pivotIndex, 1); const left = []; const right = []; const center = []; for (let i = 0; i < arr.length; i++){ if (arr[i] < pivot[0]) { left.push(arr[i]); } else if (arr[i] === pivot[0]) { center.push(arr[i]); } else { right.push(arr[i]); } } return quickSort_(left).concat([...pivot,...center], quickSort_(right)); }; result = quickSort_(tmpArr); const endTime = new Date().getTime(); return [result, endTime-startTime]; } // 快速排序优化 (Quicksort) 原地快排 const Quicksort2 = (arr=[]) => { const startTime = new Date().getTime(); if (!Array.isArray(arr)) return false; const tmpArr = arr.slice(0); let result; const Partition = (arr,start,end) => { let j = start, v = arr[j]; // 哨兵 for (let i = start+1; i <= end; i++) { if(arr[i] < v){ [arr[j + 1], arr[i]] = [arr[i], arr[j + 1]]; j++; } // if(i==Math.floor((end-start)/2)){ // [arr[start], arr[j]] = [arr[j], arr[start]]; // return Math.floor((end-start)/2); // } } [arr[start], arr[j]] = [arr[j], arr[start]]; if (j==start) return Math.ceil((end-start)/2); return j; //返回基准元素位置 } const quickSort2_ = (arr,start,end) => { if (start < end) { const mid = Partition(arr,start,end); //返回基准元素位置 quickSort2_(arr,start,mid-1); //左边快速排序 quickSort2_(arr,mid+1,end); //右边快速排序 } return arr; } result = quickSort2_(tmpArr,0,tmpArr.length-1); const endTime = new Date().getTime(); return [result, endTime-startTime]; } // 三路快排 const Quicksort3 = (arr=[]) => { const startTime = new Date().getTime(); if (!Array.isArray(arr)) return false; const tmpArr = arr.slice(0); const qsort = arr => arr.length <=1 ? arr : qsort(arr.filter(x => x < arr[0])).concat(arr.filter(x => x==arr[0])).concat(qsort(arr.filter(x => x > arr[0]))); qsort(tmpArr); const endTime = new Date().getTime(); return [tmpArr, endTime-startTime]; } // 数组自带排序 const SelfSort = (arr=[]) => { const startTime = new Date().getTime(); if (!Array.isArray(arr)) return false; const tmpArr = arr.slice(0); tmpArr.sort((a,b)=>a-b); const endTime = new Date().getTime(); return [tmpArr, endTime-startTime]; }
// 二分查找 const Binary_search = (arr, key) => { let low=0, high=arr.length-1; while(low<=high){ const mid=parseInt((high+low)/2); if(key==arr[mid]){ return mid; }else if(key>arr[mid]){ low=mid+1; }else if(key<arr[mid]){ high=mid-1; }else{ return -1; } } }
测试代码
let size = 5; const arr = new Array(size).fill('').map(() => size/20); // console.log(BubbleSort(arr)[1]); // console.log(InsertionSort(arr)[1]); // console.log(SelctionSort2(arr)[1]); // console.log(SelctionSort(arr)[1]); console.log(Quicksort(arr)[1]); // console.log(arr.join(',')); // console.log(Quicksort2(arr)[1]); console.log(Quicksort3(arr)[1]); // console.log(arr.join(',')); // console.log(SelfSort(arr)[1]); // console.log(arr.join(',')); console.log(Quicksort2([5,9,12,5,36,12,35,65,98,65,3,11,60,19,87,29,3,19,30])[0]); // console.log(Quicksort([5,9,12,5,36,12,35,65,98,65,3,11,60,19,87,29,3,19,30])[0]); // console.log(SelfSort([5,9,12,5,36,12,35,65,98,65,3,11,60,19,87,29,3,19,30])[0]);