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>

  

 

 

输出:

 

posted @ 2023-10-23 19:43  ®Geovin Du Dream Park™  阅读(8)  评论(0编辑  收藏  举报