js实现排序

80 阅读2分钟
/*
 * @Description: 
 * @version: 
 * @Author: xuml31350
 * @Date: 2020-09-14 14:39:07
 * @LastEditors: xuml31350
 * @LastEditTime: 2020-09-14 15:07:56
 */
/**
* 插入排序
* 时间复杂度O(n^2)
* @param {any} arr
* @returns
* @memberof sort
*/
const sort1 = (arr) => {
  for (let i = 1;i < arr.length;i++) {
    let temp = arr[i];
    let j = i-1;
    for (j;j >= 0;j--) {
      if(arr[j] > temp) {
        arr[j+1] = arr[j]
      } else {
        break
      }
    }
    arr[j+1] = temp;
  }

  return arr;
}

/**
* 希尔排序
* 时间复杂度 平均O(nlogn)
*
* @param {any} arr
* @returns
*
* @memberof sort
*/
const sort2 = (arr) => {
  for (let gap = Math.floor(arr.length/2);gap > 0;gap=Math.floor(gap/2)) {
    for(let i = gap;i < arr.length;i++) {
      let j = i;
      let temp = arr[j];
      for(;j >= gap;j -= gap) {
        if(arr[j-gap] > temp) {
          arr[j] = arr[j-gap];
        }else{
          break;
        }
      }
      arr[j] = temp;
    }
  }
    return arr;
}

/**
* 快速排序
* 时间复杂度O(n2) 平均O(nlongn)
*
* @param {any} arr
* @returns
* @memberof sort
*/
const sort3 = (arr) => {
  if(arr.length <= 1)
    return arr;
  let middle = Math.floor(arr.length / 2);
  let midVal = arr.splice(middle, 1)[0];
  let left = [];
  let right = [];
  for(let i = 0;i < arr.length;i++) {
    if(arr[i] < midVal) {
      left.push(arr[i])
    } else {
      right.push(arr[i]);
    }
  }
  return this.sort3(left).concat([midVal], this.sort3(right));
}

/**
    * 选择排序 时间复杂度O(n^2)
    *
    * @param {any} arr
    * @returns
    * @memberof sort
    */
const sort4 = (arr) => {
  let min = 0;
  let temp;
  for (let i = 0;i < arr.length;i++) {
    min = i
    for (let j=i+1;j<arr.length;j++) {
      if(arr[j] < arr[min]) {
        min = j
      }
    }
    temp = arr[i];
    arr[i] = arr[min];
    arr[min] = temp;
  }
  return arr;
}

/**
* 冒泡排序 时间复杂度O(n^2)
*
* @param {any} arr
* @returns
*
* @memberof sort
*/
const sort5 = (arr) => {
  for (let i=0;i<arr.length;i++) {
    for (let j=0;j<arr.length - i;j++) {
      if(arr[j+1] < arr[j]) {
        let temp = arr[j+1];
        arr[j+1] = arr[j];
        arr[j] = temp;
      }
    }
  }
  return arr;
}

/**
* 归并排序 时间复杂度O(nlogn) 空间复杂度O(n)
*
* @param {any} arr
* @returns
*
* @memberof sort
*/
const sort6 = (arr) => {
  if(arr.length < 2) {
      return arr;
  }
  let len = arr.length;
  let middleVal = Math.floor(len / 2);
  let left = arr.slice(0, middleVal);
  let right = arr.slice(middleVal, len);
  return merge(sort6(left), sort6(right));
}

/**
* 归并排序划分后进行的分割函数
* @param {any} left
* @param {any} right
* @returns
*
* @memberof sort
*/
const merge = (left, right) => {
  let result = [];
  while(left.length && right.length) {
      if(left[0] < right[0]) {
          result.push(left.shift());
      } else {
          result.push(right.shift());
      }
  }
  while (left.length) {
      result.push(left.shift());
  }
  while(right.length) {
      result.push(right.shift());
  }
  return result;
}

/**
* 堆排序 时间复杂度O(nlogn)
* 初始化建堆O(n) 排序重建堆O(nlogn)
*
* @param {any} arr
* @returns
*
* @memberof sort
*/
const sort7 = (arr) => {
  let len = arr.length;
  let tem;
 buildMaxHeap(arr);
 for(let i = len - 1; i > 0; i --){
  tem = arr[i];
  arr[i] = arr[0];
  arr[0] = tem;
  maxHeap(arr, 0 , --len);
 }
 return arr;
}
/**
* 建立最大堆
*
* @param {any} arr
*
* @memberof sort
*/
const buildMaxHeap = (arr) => {
 var lastFather = Math.floor(arr.length / 2) - 1;//堆的最后一个父节点
 for(let i = lastFather; i > 0; i --){
  maxHeap(arr, i, arr.length);
 }
}

/**
* 对重建堆排序
*
* @param {any} arr
* @param {any} index
* @param {any} heapSize
*
* @memberof sort
*/
const maxHeap = (arr, index, heapSize) =>{
 var tem = index; //记录入参元素下标
 var leftChildIndex = 2 *index + 1; //元素的左子树的元素下标
 var rightChildeIndex = 2 * index + 2;//元素的右子树的元素下标
 if( leftChildIndex < heapSize && arr[leftChildIndex] > arr[index]){
  index = leftChildIndex;
 }
 if( rightChildeIndex < heapSize && arr[rightChildeIndex] > arr[index]){
  index = rightChildeIndex;
 }
 if(index != tem){
  var t = arr[tem];
  arr[tem] = arr[index];
  arr[index] = t;
  maxHeap(arr, index, heapSize);
 }
}

/**
* 基数排序 O(d(n+radix))
* radix 基数 d为堆数
*
* @param {any} arr
* @param {any} radix 基数
* @returns
*
* @memberof sort
*/
const sort8 = (arr, radix) => {
  let max = this.findMax(arr, radix); // 找出堆数
  console.log(max);
  for(let i = 1;i <= max;i++) {
      this.buildBy(arr, i, radix);
  }
  return arr;
}

/**
* 找出堆数
*
* @param {any} arr
* @param {any} radix 基数
* @returns 堆数
*
* @memberof sort
*/
const findMax = (arr, radix) => {
  let max = 1;
  let len = arr.length;
  for (let i = 0; i < len;i++) {
    while(Math.floor(arr[i] / (radix** (max- 1))) > 1) {
      max++;
    }
  }
  return max;
}

/**
* 分桶排序
*
* @param {any} arr
* @param {any} index 当前桶
* @param {any} radix 基数
*
* @memberof sort
*/
const buildBy = (arr, index, radix) => {
  let bockets = new Array(radix);
  for (let i = 0;i < radix;i++) {
    bockets[i] = [];
  }
  for (let i = 0;i < arr.length;i++) {
    let remainder = Math.floor(arr[i] / (radix ** (index - 1))) % radix;
    bockets[remainder].push(arr[i]);
  }
  let temp = 0;
  for (let i = 0;i < bockets.length;i++) {
    for (let j = 0;j< bockets[i].length;j++) {
      arr[temp] = bockets[i][j];
      temp++
    }
  }
}