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(涂聚文)
浙公网安备 33010602011771号