JS中的睡眠排序、猴子排序和js的常见的几种排序算法

今天看到睡眠排序和猴子排序,感觉经典确实是经典,为失业编程!简单的写这两个排序,一方面可以锻炼自己的思维能力,另一方面可以进一步理解JS三座山之间的异步。

睡觉排序

睡眠排序就遇到一个数就把一个数放到一个线程里睡着,然后先醒的先放到数组里,后醒的后放到数组里,时间复杂度取决于这个数组里的最大数是多少,理论上可以达到正无穷。

JS是单线程的,可以使用setTimeout来假装一下,下面的手写使用 async 和 await 处理异步函数:

let arr = [2,4,-7,6,-9]
function getArray(numbers){
    return new Promise((resolve) => {
        let ary = []
        numbers.forEach((el) => {
            //  如果小于0 那就按照先完成的先放,后完成的后放(时间越大数越小,放在数组左边)
            if (el < 0) {
                setTimeout(() => {
                    ary.unshift(el)
                    if (ary.length === numbers.length) resolve(ary)
                }, ~(el * 4 + 4))  // 时间取正数 因为 setTimeout 的最小延迟时间是4ms以及确保0的时候也有延迟
            } else {
                setTimeout(() => {
                    ary.push(el)
                    if (ary.length === numbers.length) resolve(ary)
                }, el * 4 + 4)
            }
        })
    });
}
async function sleepSort(numbers){  //  异步函数
    let data = await getArray(numbers)  //  等待promise 完成并返回结果
    console.log(data)  //  [-9, -7, 2, 4, 6]
    return data
}
console.log(sleepSort(arr));  //  Promise{<pending>}

猴子排序

有一个经典的说法,把一直猴子和一个电脑放到一个房间里,给它无限的时间,那么他在键盘上乱敲总能敲出一部《莎士比亚》,

猴子排序就是把一个数组全部打乱,总有一次能够排序成功。这个时间复杂度依据数组长度,数越多,理论上也可以到达正无穷,但是最小时间复杂度可以到1(欧皇附体)。

猴子排序主要实现就是如何打乱整个数组的顺序,使用的方法是每一个数都与数组内的随机一个数进行交换,然后检测数组是否有序

function shuffle(numbers){
    let len = numbers.length
    while (len--){
        let random = (Math.random() * len >>> 0);  //  注意分号 否则JS会认为是()[]
            [numbers[random], numbers[len]] = [numbers[len], numbers[random]]
    }
}
function monkeySort(numbers){
    while (true){
        shuffle(numbers)
        let blo = true
        for (let i=0; i<numbers.length-1; i++){
            if (numbers[i]>numbers[i+1]){
                blo = false
                break
            }
        }
        if (blo) return
    }
}
monkeySort(arr)
console.log(arr);  //  [-9, -7, 2, 4, 6]

JavaScript 中常见的排序算法有以下几种:

冒泡排序

冒泡排序是一种简单的排序算法,它会多次遍历要排序的数列,每次遍历都会比较相邻的两个元素,如果它们的顺序错误就交换它们。

代码如下:

function bubbleSort(arr) {
  var len = arr.length;
  for (var i = 0; i < len - 1; i++) {
    for (var j = 0; j < len - 1 - i; j++) {
      if (arr[j] > arr[j+1]) {
        var temp = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = temp;
      }
    }
  }
  return arr;
}

插入排序

插入排序是一种简单直观的排序算法,它的工作原理是将未排序的元素逐个插入已排序的序列中。具体实现时,从第一个元素开始,该元素可以认为已经被排序,取出下一个元素,在已经排序的元素序列中从后向前扫描,找到合适位置并插入。

代码如下:

function insertSort(arr) {
  var len = arr.length;
  for (var i = 1; i < len; i++) {
    var key = arr[i];
    var j = i - 1;
    while (j >= 0 && arr[j] > key) {
      arr[j+1] = arr[j];
      j--;
    }
    arr[j+1] = key;
  }
  return arr;
}

快速排序

快速排序是一种常用的排序算法,基本思想是通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,然后对这两部分继续进行排序,以达到整个序列有序的目的。

代码如下:

function quickSort(arr, left, right) {
  if (left < right) {
    var pivotIndex = partition(arr, left, right);
    quickSort(arr, left, pivotIndex-1);
    quickSort(arr, pivotIndex+1, right);
  }
  return arr;
}

function partition(arr, left, right) {
  var pivot = arr[left];
  var i = left + 1;
  var j = right;
  while (i <= j) {
    while (arr[i] < pivot && i <= j) {
      i++;
    }
    while (arr[j] > pivot && i <= j) {
      j--;
    }
    if (i < j) {
      var temp = arr[i];
      arr[i] = arr[j];
      arr[j] = temp;
    }
  }
  var temp = arr[left];
  arr[left] = arr[j];
  arr[j] = temp;
  return j;
}

归并排序

归并排序是一种采用分治思想的排序算法,它的核心思想是将大问题分解为小问题来解决,并将小问题的结果合并起来得到大问题的结果。在归并排序中,将待排序数组不断拆分为左右两个子数组,直到子数组长度为1,然后再将左右两个有序子数组合并成一个有序数组。

代码如下:

function mergeSort(arr) {
  if (arr.length < 2) {
    return arr;
  }
  var middle = Math.floor(arr.length / 2);
  var leftArr = arr.slice(0, middle);
  var rightArr = arr.slice(middle);
  return merge(mergeSort(leftArr), mergeSort(rightArr));
}

function merge(leftArr, rightArr) {
  var result = [];
  while (leftArr.length && rightArr.length) {
    if (leftArr[0] < rightArr[0]) {
      result.push(leftArr.shift());
    } else {
      result.push(rightArr.shift());
    }
  }
  return result.concat(leftArr).concat(rightArr);
}

猜你喜欢

转载自blog.csdn.net/m0_64460287/article/details/129751244