javascript: Sorting Algorithms
/** * file Sort.js * ide:vscode JavaScript Sorting Algorithms * 插件:IntelliSense,JSDoc,CodeLens,Debugger for Chrome, 静态代码检查:ESLint,JSHint,Flow Langugae Support,StandardJS-JavaScript Standard Style, koroFileHeader(文件头注释), 测试插件:Mocha sidebar,Mocha Test Explorer,Jest Path Intellisense,Import Cost,Quokka.js,Code Metrics,Javascript Booster,Turbo Console Log * https://www.programiz.com/dsa/counting-sort * https://www.geeksforgeeks.org/sorting-algorithms/ * https://thedukh.com/2021/02/javascript-sorting-algorithms-explained-radix-sort/ * https://www.epubit.com/ * https://www.ituring.com.cn/ */ /** * Description placeholder 1. Bubble Sort冒泡排序法 * @date 10/23/2023 - 2:47:05 PM * * @param {*} arry 需要排序的整数數組 * @param {*} nszie 数组长度 * @returns {*} 返回排序后结果的数组 */ function BubbleSort(arry, nszie) { var i, j, temp; var swapped; for (i = 0; i < nszie - 1; i++) { swapped = false; for (j = 0; j < nszie - i - 1; j++) { if (arry[j] > arry[j + 1]) { // Swap arry[j] and arry[j+1] temp = arry[j]; arry[j] = arry[j + 1]; arry[j + 1] = temp; swapped = true; } } // IF no two elements were // swapped by inner loop, then break if (swapped == false) break; } return arry } /** * 交换操作 * @param {*} arry 数组 * @param {*} xp * @param {*} yp */ function swap(arry,xp, yp) { var temp = arry[xp]; arry[xp] = arry[yp]; arry[yp] = temp; } /** * 2 选择排序 Selection Sort * @param {*} arry 需要排序的整数數組 * @param {*} nsize 数组长度 * @returns 返回排序后结果的数组 */ function SelectionSort(arry, nsize) { var i, j, min_idx; // One by one move boundary of unsorted subarray for (i = 0; i < nsize-1; i++) { // Find the minimum element in unsorted array min_idx = i; for (j = i + 1; j < nsize; j++) if (arry[j] < arry[min_idx]) min_idx = j; // Swap the found minimum element with the first element swap(arry,min_idx, i); } return arry; } /** * 3 插入排序 Insertion Sort * @param {*} arry 需要排序的整数數組 * @param {*} nsize 数组长度 * @returns 返回排序后结果的数组 */ function InsertionSort(arry, nsize) { let i, key, j; for (i = 1; i < nsize; i++) { key = arry[i]; j = i - 1; /* Move elements of arr[0..i-1], that are greater than key, to one position ahead of their current position */ while (j >= 0 && arry[j] > key) { arry[j + 1] = arry[j]; j = j - 1; } arry[j + 1] = key; } return arry; } // // Merges two subarrays of arr[]. // First subarray is arr[l..m] // Second subarray is arr[m+1..r] /** * * @param {*} arry 需要打印的数组 * @param {*} indexStart * @param {*} m * @param {*} indexEnd */ function merge(arry, indexStart, m, indexEnd) { var n1 = m - indexStart + 1; var n2 = indexEnd - m; // Create temp arrays var L = new Array(n1); var R = new Array(n2); // Copy data to temp arrays L[] and R[] for (var i = 0; i < n1; i++) L[i] = arry[indexStart + i]; for (var j = 0; j < n2; j++) R[j] = arry[m + 1 + j]; // Merge the temp arrays back into arry[l..r] // Initial index of first subarray var i = 0; // Initial index of second subarray var j = 0; // Initial index of merged subarray var k = indexStart; while (i < n1 && j < n2) { if (L[i] <= R[j]) { arry[k] = L[i]; i++; } else { arry[k] = R[j]; j++; } k++; } // Copy the remaining elements of // L[], if there are any while (i < n1) { arry[k] = L[i]; i++; k++; } // Copy the remaining elements of // R[], if there are any while (j < n2) { arry[k] = R[j]; j++; k++; } } // l is for left index and r is // right index of the sub-array // of arr to be sorted /** * 4 合并排序 Merge Sort * @param {*} arry 需要排序的整数數組 * @param {*} indexStart 数组索引值 0 * @param {*} indexEnd 索引值最大值 数组长度-1 * @returns 返回排序好的数组 */ function mergeSort(arry,indexStart, indexEnd){ if(indexStart>=indexEnd){ return; } var m =indexStart+ parseInt((indexEnd-indexStart)/2); mergeSort(arry,indexStart,m); mergeSort(arry,m+1,indexEnd); merge(arry,indexStart,m,indexEnd); return arry; } /** * Function to partition the array and return the partition index * @param {*} arry 需要排序的整数數組 * @param {*} low 数组索引值 0 * @param {*} high 索引值最大值 数组长度-1 * @returns */ function quickPartition(arry, low, high) { // Choosing the pivot let pivot = arry[high]; // Index of smaller element and indicates the right position of pivot found so far let i = low - 1; for (let j = low; j <= high - 1; j++) { // If current element is smaller than the pivot if (arry[j] < pivot) { // Increment index of smaller element i++; [arry[i], arry[j]] = [arry[j], arry[i]]; // Swap elements } } [arry[i + 1], arry[high]] = [arry[high], arry[i + 1]]; // Swap pivot to its correct position return i + 1; // Return the partition index } /** * The main function that implements QuickSort * 5 Quick Sort 快速排序 * @param {*} arry 需要排序的整数數組 * @param {*} low 数组索引值 0 * @param {*} high 索引值最大值 数组长度-1 * @returns 返回排序好的数组 */ function quickSort(arry, low, high) { if (low < high) { // pi is the partitioning index, arr[pi] is now at the right place let pi = quickPartition(arry, low, high); // Separately sort elements before partition and after partition quickSort(arry, low, pi - 1); quickSort(arry, pi + 1, high); } return arry; } /** * of Heap Sort * 6 堆排序 Heap Sort * @param {*} arry 需要排序的整数數組 * @returns 返回排序好的数组 */ function heapSort( arry) { var N = arry.length; // Build heap (rearrange array) for (var i = Math.floor(N / 2) - 1; i >= 0; i--) heapify(arry, N, i); // One by one extract an element from heap for (var i = N - 1; i > 0; i--) { // Move current root to end var temp = arry[0]; arry[0] = arry[i]; arry[i] = temp; // call max heapify on the reduced heap heapify(arry, i, 0); } return arry; } /** * To heapify a subtree rooted with node i which is * an index in arr[]. n is size of heap * @param {*} arry 需要排序的整数數組 * @param {*} N 数组长度 * @param {*} i 数组索引值 0 */ function heapify(arry, N, i) { var largest = i; // Initialize largest as root var l = 2 * i + 1; // left = 2*i + 1 var r = 2 * i + 2; // right = 2*i + 2 // If left child is larger than root if (l < N && arry[l] > arry[largest]) largest = l; // If right child is larger than largest so far if (r < N && arry[r] > arry[largest]) largest = r; // If largest is not root if (largest != i) { var swap = arry[i]; arry[i] = arry[largest]; arry[largest] = swap; // Recursively heapify the affected sub-tree heapify(arry, N, largest); } } /** * 7 Counting Sort 计数排序 * @param {*} arry 需要排序的整数數組 * @param {*} min 数组中最小的值 * @param {*} max 数组中最大的值 * @returns 返回排序好的数组 */ function countingSort(arry, min, max) { let j = 0; let supplementary = []; for (let i = min; i <= max; i++) { supplementary[i] = 0; } for (let i=0; i < arry.length; i++) { supplementary[arry[i]] += 1; } for (let i = min; i <= max; i++) { while (supplementary[i] > 0) { arry[j++] = i; supplementary[i] -= 1; } } return arry; } /** * 7 Counting Sort 计数排序 * @param {*} arry 需要排序的整数數組 * @returns 返回排序好的数组 */ function duCountingSort(arry) { let j = 0; let supplementary = []; min=getArrayMin(arry); max=getArrayMax(arry); for (let i = min; i <= max; i++) { supplementary[i] = 0; } for (let i=0; i < arry.length; i++) { supplementary[arry[i]] += 1; } for (let i = min; i <= max; i++) { while (supplementary[i] > 0) { arry[j++] = i; supplementary[i] -= 1; } } return arry; } /** * 求得数组中最大值 * @param {*} arry 整数數組 * @param {*} nszie 数组长度 * @returns 返回数组中的最大值 */ function getMax(arry,nszie) { let mx = arry[0]; for (let i = 1; i < nszie; i++) if (arry[i] > mx) mx = arry[i]; return mx; } /** * 求得数组中最小值 * @param {*} arry 整数數組 * @returns 返回数组中的最小值 */ function getArrayMin(arry){ var min = arry[0]; for(var i = 1, ilen = arry.length; i < ilen; i+=1) { if(arry[i] < min) { min = arry[i]; } } return min; } /** * 求得数组中最大值 * @param {*} arry 整数數組 * @returns 返回数组中的最大值 */ function getArrayMax(arry) { var max = arry[0]; for(var i = 1,ilen = arry.length; i < ilen; i++) { if(arry[i] > max) { max = arry[i]; } } return max; } /** * * @param {*} arry * @param {*} nszie * @param {*} exp */ function radixCountSort(arry,nszie,exp) { let output = new Array(nszie); // output array let i; let x; let count = new Array(10); for(let i=0;i<10;i++) count[i]=0; // Store count of occurrences in count[] 这里有问题 for (i = 0; i < nszie; i++) { let s=arry[i]/exp; x = Math.floor(s) % 10; } count[x]++; // Change count[i] so that count[i] now contains // actual position of this digit in output[] for (i = 1; i < 10; i++) count[i] += count[i - 1]; // Build the output array for (i = nszie - 1; i >= 0; i--) { output[count[x] - 1] = arry[i]; count[x]--; } // Copy the output array to arr[], so that arr[] now // contains sorted numbers according to current digit for (i = 0; i < nszie; i++) arry[i] = output[i]; } /** * The main function to that sorts arr[] of size n using 8 Radix Sort 基数排序 Radix Sort 有问题 * @param {*} arry 需要排序的整数數組 * @param {*} nszie 数组长度 */ function radixsort(arry,nszie) { // Find the maximum number to know number of digits let m = getMax(arry, nszie); // Do counting sort for every digit. Note that // instead of passing digit number, exp is passed. // exp is 10^i where i is current digit number for (let exp = 1; Math.floor(m / exp) > 0; exp *= 10) radixCountSort(arry, nszie, exp); return arry; } /** * * @param {*} arry * @returns */ function getBiggestDigitCount(arry) { let maxDigits = 0; for (let i = 0; i < arry.length; i++) { maxDigits = Math.max(maxDigits, arry[i].toString().length); } return maxDigits; } /** * * @param {*} arry * @param {*} i * @returns */ function getDigitAtPlace(arry, i) { return arry.toString().split("").reverse()[i] || 0; } /** * 8 Radix Sort 基数排序 * @param {*} arry 需要排序的整数數組 * @returns 返回排序后结果的数组 */ function DuRadixSort(arry) { let maxDigits = getBiggestDigitCount(arry); for (let i = 0; i < maxDigits; i++) { let bucketArray = Array.from({ length: 10 }, () => []); for (let j = 0; j < arry.length; j++) { let digit = getDigitAtPlace(arry[j], i); bucketArray[digit].push(arry[j]); } arry = [].concat(...bucketArray); } return arry; } /** * 9. Bucket Sort 桶排序 * using bucket sort * @param {*} arry 需要排序的整数數組 * @param {*} nszie 数组长度 * @returns 返回排序后结果的数组 */ function bucketSort(arry,nszie) { if (nszie <= 0) return; // 1) Create n empty buckets let buckets = new Array(nszie); for (let i = 0; i < nszie; i++) { buckets[i] = []; } // 2) Put array elements in different buckets for (let i = 0; i < nszie; i++) { let idx = arry[i] * nszie; let flr = Math.floor(idx); //buckets[flr].push(arry[i]); //有问题 buckets[flr].push(arry[i]); } // 3) Sort individual buckets for (let i = 0; i < nszie; i++) { buckets[i].sort(function(a,b){return a-b;}); } // 4) Concatenate all buckets into arr[] let index = 0; for (let i = 0; i < nszie; i++) { for (let j = 0; j < buckets[i].length; j++) { arry[index++] = buckets[i][j]; } } return arry; } /** * 9. Bucket Sort 桶排序 * @param {*} arry 需要排序的整数數組 * @returns 返回排序后结果的数组 */ function duBubbleSort(arry) { let swapHappened; for (let i = arry.length; i > 0; i--) { swapHappened = true; for (let j = 0; j < i - 1; j++) { if (arry[j] > arry[j + 1]) { [arry[j], arry[j + 1]] = [arry[j + 1], arry[j]]; swapHappened = false; } } if (swapHappened) { break; } } return arry; } /** * 10.宾果排序 Bingo Sort * @param {*} arry 需要排序的整数數組 * @returns 返回排序后结果的数组 */ function bingoSort(arry) { let n=arry.length; let bingo = arry[0]; let nextBingo = arry[0]; //let mx= Math.max(...arry); //let mi= Math.min(...arry); // For finding the maximum and minimum element of // the Array for (let i = 1; i < n; bingo = Math.min(bingo, arry[i]), nextBingo = Math.max(nextBingo, arry[i]), i++) ; let largestEle = nextBingo; let nextElePos = 0; while (bingo < nextBingo) { // Will keep the track of the element position to // shifted to their correct position let startPos = nextElePos; for (let i = startPos; i < n; i++) { if (arry[i] == bingo) { [arry[i], arry[nextElePos]] = [arry[nextElePos], arry[i]]; nextElePos = nextElePos + 1; } // Here we are finding the next Bingo Element // for the next pass else if (arry[i] < nextBingo) nextBingo = arry[i]; } bingo = nextBingo; nextBingo = largestEle; } for (let i = 0; i < arry.length; i++) { // console.log("arr: ",arry[i]); } return arry; } /** * 11. 希尔排序 Shell Sort * * @param {*} arry * @returns */ function shellSort(arry) { let n = arry.length; // Start with a big gap, then reduce the gap for (let gap = Math.floor(n/2); gap > 0; gap = Math.floor(gap/2)) { // Do a gapped insertion sort for this gap size. // The first gap elements a[0..gap-1] are already // in gapped order keep adding one more element // until the entire array is gap sorted for (let i = gap; i < n; i += 1) { // add a[i] to the elements that have been gap // sorted save a[i] in temp and make a hole at // position i let temp = arry[i]; // shift earlier gap-sorted elements up until // the correct location for a[i] is found let j; for (j = i; j >= gap && arry[j - gap] > temp; j -= gap) arry[j] = arry[j - gap]; // put temp (the original a[i]) in its correct // location arry[j] = temp; } } return arry; } let MIN_MERGE = 32; /** * * @param {*} n * @returns */ function minRunLength(n) { // Becomes 1 if any 1 bits are shifted off let r = 0; while (n >= MIN_MERGE) { r |= (n & 1); n >>= 1; } return n + r; } // This function sorts array from left index to // to right index which is of size atmost RUN function TimeInsertionSort(arry,left,right) { for(let i = left + 1; i <= right; i++) { let temp = arry[i]; let j = i - 1; while (j >= left && arry[j] > temp) { arry[j + 1] = arry[j]; j--; } arry[j + 1] = temp; console.log(arry); } } // Merge function merges the sorted runs /** * * @param {*} arry * @param {*} l * @param {*} m * @param {*} r */ function TimeMerge(arry, l, m, r) { // Original array is broken in two parts // left and right array let len1 = m - l + 1, len2 = r - m; let left = new Array(len1); let right = new Array(len2); for(let x = 0; x < len1; x++) { left[x] = arry[l + x]; } for(let x = 0; x < len2; x++) { right[x] = arry[m + 1 + x]; } let i = 0; let j = 0; let k = l; // After comparing, we merge those two // array in larger sub array while (i < len1 && j < len2) { if (left[i] <= right[j]) { arry[k] = left[i]; i++; } else { arry[k] = right[j]; j++; } k++; } // Copy remaining elements // of left, if any while (i < len1) { arry[k] = left[i]; k++; i++; } // Copy remaining element // of right, if any while (j < len2) { arry[k] = right[j]; k++; j++; } } // Iterative Timesort function to sort the // array[0...n-1] (similar to merge sort) /** * 12.Time Sort * @param {*} arry * @param {*} nsize */ function timeSort(arry, nsize) { let minRun = minRunLength(MIN_MERGE); // Sort individual subarrays of size RUN for(let i = 0; i < nsize; i += minRun) { TimeInsertionSort(arry, i, Math.min( (i + MIN_MERGE - 1), (nsize - 1))); } // Start merging from size // RUN (or 32). It will // merge to form size 64, // then 128, 256 and so on // .... for(let size = minRun; size < nsize; size = 2 * size) { // Pick starting point // of left sub array. We // are going to merge // arr[left..left+size-1] // and arr[left+size, left+2*size-1] // After every merge, we // increase left by 2*size for(let left = 0; left < nsize; left += 2 * size) { // Find ending point of left sub array // mid+1 is starting point of right sub // array let mid = left + size - 1; let right = Math.min((left + 2 * size - 1), (n - 1)); // Merge sub array arr[left.....mid] & // arr[mid+1....right] if(mid < right) TimeMerge(arry, left, mid, right); } } return arry; } /** * * @param {*} gap * @returns */ function getNextGap(gap) { // Shrink gap by Shrink factor gap = parseInt((gap*10)/13, 10); if (gap < 1) return 1; return gap; } /** * Function to sort arr[] using Comb Sort * 13 Comb Sort * @param {*} arry */ function CombSort(arry) { let n = arry.length; // initialize gap let gap = n; // Initialize swapped as true to // make sure that loop runs let swapped = true; // Keep running while gap is more than // 1 and last iteration caused a swap while (gap != 1 || swapped == true) { // Find next gap gap = getNextGap(gap); // Initialize swapped as false so that we can // check if swap happened or not swapped = false; // Compare all elements with current gap for (let i=0; i<n-gap; i++) { if (arry[i] > arry[i+gap]) { // Swap arr[i] and arr[i+gap] let temp = arry[i]; arry[i] = arry[i+gap]; arry[i+gap] = temp; // Set swapped swapped = true; } } } return arry; } /** * 14 Pigeonhole Sort 鸽巢排序 * @param {*} arry * @param {*} nszie * @returns */ function pigeonholeSort(arry, nszie) { let min = arry[0]; let max = arry[0]; let range, i, j, index; for(let a = 0; a < nszie; a++) { if(arry[a] > max) max = arry[a]; if(arry[a] < min) min = arry[a]; } range = max - min + 1; let phole = []; for(i = 0; i < nszie; i++) phole[i] = 0; for(i = 0; i < nszie; i++) phole[arry[i] - min]++; index = 0; for(j = 0; j < range; j++) while(phole[j] --> 0) arry[index++] = j + min; return arry; } /** * 15 循环排序 * @param {*} arry * @param {*} nszie * @returns */ function cycleSort(arry, nszie) { // count number of memory writes let writes = 0; // traverse array elements and put it to on // the right place for (let cycle_start = 0; cycle_start <= nszie - 2; cycle_start++) { // initialize item as starting point let item = arry[cycle_start]; // Find position where we put the item. We basically // count all smaller elements on right side of item. let pos = cycle_start; for (let i = cycle_start + 1; i < nszie; i++) if (arry[i] < item) pos++; // If item is already in correct position if (pos == cycle_start) continue; // ignore all duplicate elements while (item == arry[pos]) pos += 1; // put the item to it's right position if (pos != cycle_start) { let temp = item; item = arry[pos]; arry[pos] = temp; writes++; } // Rotate rest of the cycle while (pos != cycle_start) { pos = cycle_start; // Find position where we put the element for (let i = cycle_start + 1; i < nszie; i++) if (arry[i] < item) pos += 1; // ignore all duplicate elements while (item == arry[pos]) pos += 1; // put the item to it's right position if (item != arry[pos]) { let temp = item; item = arry[pos]; arry[pos] = temp; writes++; } } } return arry; } /** * 16 Cocktail Sort 鸡尾酒排序 * @param {*} arry * @returns */ function cocktailSort(arry) { let swapped = true; let start = 0; let end = arry.length; while (swapped == true) { // reset the swapped flag on entering the // loop, because it might be true from a // previous iteration. swapped = false; // loop from bottom to top same as // the bubble sort for (let i = start; i < end - 1; ++i) { if (arry[i] > arry[i + 1]) { let temp = arry[i]; arry[i] = arry[i + 1]; arry[i + 1] = temp; swapped = true; } } // if nothing moved, then array is sorted. if (swapped == false) break; // otherwise, reset the swapped flag so that it // can be used in the next stage swapped = false; // move the end point back by one, because // item at the end is in its rightful spot end = end - 1; // from top to bottom, doing the // same comparison as in the previous stage for (let i = end - 1; i >= start; i--) { if (arry[i] > arry[i + 1]) { let temp = arry[i]; arry[i] = arry[i + 1]; arry[i + 1] = temp; swapped = true; } } // increase the starting point, because // the last stage would have moved the next // smallest number to its rightful spot. start = start + 1; } return arry; } /** * 17.Strand Sort 经典排序 * @param {*} arry * @returns */ function strandSort(arry) { // To store sorted output list var op=[]; //list helping in merge operation var opp=[]; // Create a sorted sublist with // first item of input list as // first item of the sublist var sublist=[]; sublist.push(arry[0]); arry.shift(); // Traverse remaining items of ip list var len=arry.length-1;//last index of input list var len2=sublist.length-1;//last index of sublist var it =0; while(it<=len){ // If current item of input list // is greater than last added item // to sublist, move current item // to sublist as sorted order is // maintained. if (arry[it] >sublist[len2]) { sublist.push(arry[it]); len2++; // splice(index,1) on list removes an // item and moves "it" to // next of removed item. arry.splice(it,1); } // Otherwise ignore current element else{ it++; } } // Merge current sublist into output while(sublist.length>0 && op.length>0){ if(sublist[0]>=op[0]){opp.push(op.shift());} else{opp.push(sublist.shift());} } if(sublist.length==0){ opp=[...opp,...op]; } if(op.length==0){ opp=[...opp,...sublist]; } op=[...opp]; opp.length=0; // Recur for remaining items in input and current items in op. //Added base case if(arry.length>0){ strandSort(arry); } return op; } //--------------------- /* JavaScript program for Bitonic Sort. Note that this program works only when size of input is a power of 2. */ /* The parameter dir indicates the sorting direction, ASCENDING or DESCENDING; if (a[i] > a[j]) agrees with the direction, then a[i] and a[j] are interchanged. */ /** * * @param {*} arry * @param {*} i * @param {*} j * @param {*} dir */ function compAndSwap(arry, i, j, dir) { if ((arry[i] > arry[j] && dir === 1) || (arry[i] < arry[j] && dir === 0)) { // Swapping elements var temp = arry[i]; arry[i] = arry[j]; arry[j] = temp; } } /* It recursively sorts a bitonic sequence in ascending order, if dir = 1, and in descending order otherwise (means dir=0). The sequence to be sorted starts at index position low, the parameter cnt is the number of elements to be sorted.*/ /** * * @param {*} arry * @param {*} low * @param {*} cnt * @param {*} dir */ function bitonicMerge(arry, low, cnt, dir) { if (cnt > 1) { var k = parseInt(cnt / 2); for (var i = low; i < low + k; i++) compAndSwap(arry, i, i + k, dir); bitonicMerge(arry, low, k, dir); bitonicMerge(arry, low + k, k, dir); } } /* This function first produces a bitonic sequence by recursively sorting its two halves in opposite sorting orders, and then calls bitonicMerge to make them in the same order */ /** * * @param {*} arry * @param {*} low * @param {*} cnt * @param {*} dir */ function dubitonicSort(arry, low, cnt, dir) { if (cnt > 1) { var k = parseInt(cnt / 2); // sort in ascending order since dir here is 1 dubitonicSort(arry, low, k, 1); // sort in descending order since dir here is 0 dubitonicSort(arry, low + k, k, 0); // Will merge whole sequence in ascending order // since dir=1. bitonicMerge(arry, low, cnt, dir); } } /*Caller of bitonicSort for sorting the entire array of length N in ASCENDING order */ /** * * @param {*} arry 18. bitonic Sort 双调排序 * @param {*} nszie * @param {*} up 1 * @returns */ function bitonicSort(arry, nszie, up) { // console.log("bitonic:"+a); dubitonicSort(arry, 0, nszie, up); return arry; } /** * * @param {*} arry * @param {*} i */ function flip(arry, i) { let temp, start = 0; while (start < i) { temp = arry[start]; arry[start] = arry[i]; arry[i] = temp; start++; i--; } } // Returns index of the // maximum element in // arr[0..n-1] /** * * @param {*} arry * @param {*} n * @returns */ function findMax(arry, n) { let mi, i; for (mi = 0, i = 0; i < n; ++i) if (arry[i] > arry[mi]) mi = i; return mi; } // The main function that // sorts given array using // flip operations /** * 19. Pancake Sort * @param {*} arry * @param {*} nszie * @returns */ function pancakeSort(arry, nszie) { // Start from the complete // array and one by one // reduce current size by one for (let curr_size = nszie; curr_size > 1; --curr_size) { // Find index of the // maximum element in // arr[0..curr_size-1] let mi = findMax(arry, curr_size); // Move the maximum element // to end of current array // if it's not already at // the end if (mi != curr_size - 1) { // To move at the end, // first move maximum // number to beginning flip(arry, mi); // Now move the maximum // number to end by // reversing current array flip(arry, curr_size - 1); } } return arry;//0; } /** * * @param {*} arry * @param {*} nszie * @returns */ function isSorted(arry, nszie){ for(var i = 1; i < arry.length; i++) if (arry[i] < arry[i-1]) return false; return true; } //swap function function swap(arry, xp, yp){ var temp = arry[xp]; arry[xp] = arry[yp]; arry[yp] = temp; } // To generate permutation of the array function shuffle(arry, nszie){ var i, j=nszie; for (i=0; i < nszie; i++){ var ind = Math.floor(Math.random() * nszie); swap(arry, j-i-1, ind); } return arry; } // Sorts array a[0..n-1] using Bogo sort /** * 20. Bogo Sort * @param {*} arry * @param {*} nszie * @returns */ function bogoSort(arry, nszie){ // if array is not sorted then shuffle // the array again while (!isSorted(arry, nszie)) arry = shuffle(arry, nszie); return arry; } /** * 21. Gnome Sort * @param {*} arry * @param {*} nszie * @returns * */ function gnomeSort(arry, nszie) { let index = 0; while (index < nszie) { if (index == 0) index++; if (arry[index] >= arry[index - 1]) index++; else { let temp = 0; temp = arry[index]; arry[index] = arry[index - 1]; arry[index - 1] = temp; index--; } } return arry; } // Function to implement stooge sort h= nszie - 1 /** * 22.Stooge Sort * @param {*} arry * @param {*} nszie * @param {*} h =nszie - 1 * @returns */ function stoogeSort(arry, nszie, h) { if (nszie >= h) return; // If first element is smaller // than last, swap them if (arry[nszie] > arry[h]) { let t = arry[nszie]; arry[nszie] = arry[h]; arry[h] = t; } // If there are more than 2 // elements in the array if (h - nszie + 1 > 2) { let t = parseInt((h - nszie + 1) / 3, 10); // Recursively sort first // 2/3 elements stoogeSort(arry, nszie, h - t); // Recursively sort last // 2/3 elements stoogeSort(arry, nszie + t, h); // Recursively sort first // 2/3 elements again to // confirm stoogeSort(arry, nszie, h - t); } return arry; } /** * 打印数组 * @param {*} arry 需要找印的数组 * @param {*} nsize 数组长度 * @returns 返回打印的格式字符串 */ function printArray(arry, nsize) { var getstr=""; var i; for (i = 0; i < nsize; i++) { console.log(arry[i] + " "); getstr=getstr+arry[i]+" "; } return getstr; } /** * 整数数组转字符串显示 * @param {*} arry 需要打印的数组 * @param {*} nsize 数组的长度 * * @returns 返回打印格式字符串 */ function stringArray(arry, nsize) { var myStr=new Array(); var i; for (i = 0; i < nsize; i++) { //getstr=getstr+arry[i].toString() + "<br/>"; myStr[i]=arry[i]; console.log(arry[i]); } console.log(myStr.join("<br/>")); return myStr.join(" <br/>"); //console.log(arry); /* var myStr=new Array(); var getstr=""; */ /* var i; for (i = 0; i < nsize; i++) { getstr=getstr+arry[i] + " "; myStr[i]=arry[i].toString(); console.log(myStr[i]); } return getstr;//myStr.join(" ");*/ }
调用:
<!-- * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git * @Date: 2023-10-23 12:26:05 * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git * @LastEditTime: 2023-10-25 12:45:27 * @FilePath: \algorithms\1.html alt+ctrl+i 键 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE --> <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>成长开始,geovindu,涂聚文,Geovin Du Bubble Sort冒泡排序法</title> <meta name="Description" content="geovindu"/> <meta name="Keywords" content="geovindu"/> <meta name="author" content="geovindu"/> <script src="js/jquery-3.6.0.js"></script> <script src="js/SortAlgorithm/Sort.js"></script> <script type="text/javascript"> $(document).ready(function () { // 1. Bubble Sort冒泡排序法 var arry = [ 64, 34, 25, 112, 220, 1, 90 ]; var nzie= arry.length; var duselect=SelectionSort(arry,nzie); console.log(duselect) var geovindu=BubbleSort(arry, nzie); console.log(geovindu); var inserttdu=InsertionSort(arry,nzie); var myStr=new Array(); var i; for (i = 0; i < nzie; i++) { //getstr=getstr+arry[i].toString() + "<br/>"; myStr[i]=geovindu[i].toString(); console.log(geovindu[i].toString()); } var getstr=printArray(arry, nzie); console.log("str:"+getstr) $("#txtgeovindu").html(getstr); txtgeovindu.innerHTML = getstr;//stringArray(geovindu,nsize); console.log(myStr.join("<br/>")); var du=stringArray(arry,nzie); var du2=stringArray(duselect,nzie); var du3=stringArray(inserttdu,nzie); var dumergeSort=mergeSort(arry,0,nzie-1); var du4=stringArray(dumergeSort,nzie); console.log("mergesoft:"+dumergeSort); var duQuick=quickSort(arry,0,nzie-1); var du5=stringArray(duQuick,nzie); var duHeap=heapSort(arry,0,nzie-1); var du6=stringArray(duHeap,nzie-1); var duCounting=duCountingSort(arry); var du7=stringArray(duCounting,nzie); let duarry=[170, 45, 75, 90, 802, 24, 2, 66]; var duradix=DuRadixSort(duarry); var du8=stringArray(duradix,nzie); let arrdu = [0.897, 0.565, 0.656, 0.1234, 0.665, 0.3434]; var dubucket=duBubbleSort(arrdu); var du9=stringArray(dubucket,nzie); var dubingo=bingoSort(arry); var du10=stringArray(dubingo,nzie); var duShell=shellSort(arry); var du11=stringArray(duShell,nzie); var dutime=timeSort(arry,nzie); var du12=stringArray(dutime,nzie); var duComb=CombSort(arry,nzie); var du13=stringArray(duComb,nzie); var dudupigeonhole=pigeonholeSort(arry,nzie); var du14=stringArray(dudupigeonhole,nzie); var ducycle=cycleSort(arry,nzie); var du15=stringArray(ducycle,nzie); var ducocktailSort=cocktailSort(arry); var du16=stringArray(ducocktailSort,nzie); var dustrandSort=strandSort(arry); var du17=stringArray(dustrandSort,nzie); var a = [23, 57, 34, 38, 16, 12, 11, 15]; var up = 1; var dubitonic=bitonicSort(a,a.length,up); var du18=stringArray(dubitonic,a.length); // var dupancake=pancakeSort(a,a.length); var du19=stringArray(dupancake,a.length); var dubogo=bogoSort(a,a.length); var du20=stringArray(dubogo,a.length); var dugnome=gnomeSort(a,a.length); var du21=stringArray(dugnome,a.length); //stoogeSort var dustooge=stoogeSort(a,a.length,a.length-1); var du22=stringArray(a,a.length); console.log("bitonic Sort:"+dubitonic); console.log(du18); console.log(du); console.log("Bubble Sorted array: "); $("#geovindu").html("1.泡冒泡排序Bubble Sorted:<br/>"+myStr.join("<br/>")); $("#geovindu1").html(du); $("#geovindu2").html("2.选择排序Selection Sorted:<br/>"+du2); $("#geovindu3").html("3.插入排序Insertion Sorted:<br/>"+du3); $("#geovindu4").html("4.合并排序 Merge Sort :<br/>"+du4); $("#geovindu5").html("5.快速排序 Quick Sort:<br/>"+du5); $("#geovindu6").html("6.堆排序 Heap Sort:<br/>"+du6); $("#geovindu7").html("7.计数排序 Counting Sort:<br/>"+du7); $("#geovindu8").html("8.基数排序 Radix Sort:<br/>"+du8); $("#geovindu9").html("9.桶排序 Bucket Sort:<br/>"+du9); $("#geovindu10").html("10.宾果排序 Bingo Sort:<br/>"+du10); $("#geovindu11").html("11.希尔排序 Shell Sort:<br/>"+du11); $("#geovindu12").html("12.Time Sort:<br/>"+du12); $("#geovindu13").html("13.Comb Sort:<br/>"+du13); $("#geovindu14").html("14.Pigeonhole Sort:<br/>"+du14); $("#geovindu15").html("15.Cycle Sort:<br/>"+du15); $("#geovindu16").html("16.Cocktail Sort:<br/>"+du16); $("#geovindu17").html("17.Strand Sort:<br/>"+du17); $("#geovindu18").html("18.Bitonic Sort:<br/>"+du18); $("#geovindu19").html("19.Pancake Sort:<br/>"+du19); $("#geovindu20").html("20.Bogo Sort:<br/>"+du20); $("#geovindu21").html("21.Gnome Sort:<br/>"+du21); $("#geovindu22").html("22.stooge Sort:<br/>"+du22); }); </script> </head> <body> <textarea id="txtgeovindu" class="geovindu" name="" cols="30" rows="10"></textarea> <div id="geovindu"></div> <div id="geovindu2"></div> <div id="geovindu3"></div> <div id="geovindu4"></div> <div id="geovindu5"></div> <div id="geovindu6"></div> <div id="geovindu7"></div> <div id="geovindu8"></div> <div id="geovindu9"></div> <div id="geovindu10"></div> <div id="geovindu11"></div> <div id="geovindu12"></div> <div id="geovindu13"></div> <div id="geovindu14"></div> <div id="geovindu15"></div> <div id="geovindu16"></div> <div id="geovindu17"></div> <div id="geovindu18"></div> <div id="geovindu19"></div> <div id="geovindu20"></div> <div id="geovindu21"></div> <div id="geovindu22"></div> </body> </html>
输出:
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)