十大排序算法及其实现

91 阅读1分钟

前几天有人问我排序算法有哪些,能不能写一下快速排序,这几天慢慢的写一下整理一下吧

  • 冒泡排序
function bubbleSort(nums: number[]) {
  for (let i = nums.length - 1; i > 0; ) {
    let ti = 0;
    for (let j = 0; j < i; j++) {
      //执行交换
      if (nums[j] > nums[j + 1]) {
        const temp = nums[j];
        nums[j] = nums[j + 1];
        nums[j + 1] = temp;
        ti = j;
      }
    }
    i = ti;
  }
  return nums;
}

const bubbleRes = bubbleSort([23, 5, 7, 0, 1, 2, 7]);
  • 选择排序
function chooseSort(nums: number[]) {
  for (let i = 0; i < nums.length - 1; i++) {
    let temp = i;
    for (let j = i + 1; j < nums.length; j++) {
      if (nums[j] > nums[temp]) {
        temp = j;
      }
    }
    let x = nums[i];
    nums[i] = nums[temp];
    nums[temp] = x;
  }
  return nums;
}

const chooseRes = chooseSort([23, 5, 7, 0, 1, 2, 7]);
  • 插入排序
function insertSort(nums: number[]) {
  for (let i = 1; i < nums.length; i++) {
    for (let j = i; j > 0; j--) {
      if (nums[j] < nums[j - 1]) {
        let temp = nums[j];
        nums[j] = nums[j - 1];
        nums[j - 1] = temp;
      } else {
        break;
      }
    }
  }
  return nums;
}

  • 希尔排序
function shellSort(nums: number[]) {
  let di = Math.floor((nums.length - 1) / 2);
  while (di >= 1) {
    di = Math.floor(di / 2);
    for (let i = di; i < nums.length; i++) {
      for (let j = i; j >= di; ) {
        const ti = j - di;
        if (nums[ti] > nums[j]) {
          const temp = nums[ti];
          nums[ti] = nums[j];
          nums[j] = temp;
        } else {
          break;
        }
        j = ti;
      }
    }
  }
  return nums;
}

  • 归并排序
function mergeSort(nums: number[]) {
  function mergeSort(nums: number[], start: number, end: number) {
    if (start === end) {
      return [nums[start]];
    }
    const mid = Math.floor((start + end) / 2);
    const firstPart = mergeSort(nums, start, mid);
    const lastPart = mergeSort(nums, mid + 1, end);
    const res = [];
    let i = 0,
      j = 0;
    while (i < firstPart.length && j < lastPart.length) {
      res.push(firstPart[i] > lastPart[j] ? lastPart[j++] : firstPart[i++]);
    }
    while (i < firstPart.length) {
      res.push(firstPart[i++]);
    }
    while (j < lastPart.length) {
      res.push(lastPart[j++]);
    }
    return res;
  }
  return mergeSort(nums, 0, nums.length - 1);
}
  • 快速排序
function fastSort(nums: number[]) {
  function oneFastSort(nums: number[], firstIndex: number, lastIndex: number) {
    if (firstIndex >= lastIndex) {
      return nums;
    }
    let start = firstIndex,
      end = lastIndex;
    let temp = nums[start];
    while (start < end) {
      while (nums[end] >= temp && start < end) {
        end--;
      }
      if (start < end) {
        nums[start] = nums[end];
        nums[end] = nums[++start];
      }
    }
    nums[start] = temp;
    oneFastSort(nums, firstIndex, start - 1);
    oneFastSort(nums, start + 1, lastIndex);
  }
  oneFastSort(nums, 0, nums.length - 1);
  return nums;
}

const res = fastSort([3, 4, 7, 1, 9, 0, 3]);
  • 堆排序

function heapSort(nums: number[]) {
  function initHeap(nums: number[]) {
    for (let i = nums.length - 1; i > 0; i--) {
      const father = Math.floor((i - 1) / 2);
      if (nums[i] > nums[father]) {
        _swap(nums, i, father);
      }
    }
  }

  initHeap(nums);

  for (let i = nums.length - 1; i > 0; i--) {
    _swap(nums, 0, i);
    for (let j = 0, leftSon = 2 * j + 1; leftSon < i; ) {
      const maxSon =
        leftSon + 1 < i && nums[leftSon] < nums[leftSon + 1]
          ? leftSon + 1
          : leftSon;
      if (nums[j] < nums[maxSon]) {
        _swap(nums, j, maxSon);
        j = maxSon;
        leftSon = 2 * j + 1;
      } else {
        break;
      }
    }
  }

  return nums;
}

const heapRes = heapSort([3, 4, 7, 1, 9, 0, 3]);
  • 计数排序
function countSort(nums: number[]) {
  const [min, max] = _getMinOrMax(nums);
  const arr = new Array(max - min + 1).fill(0);
  nums.forEach((item) => {
    const k = item - min;
    arr[k] = arr[k] + 1;
  });
  let i = 0;
  arr.forEach((count, index) => {
    nums.fill(index + min, i, i + count);
    i = i + count;
  });
  return nums;
}

const countRes = countSort([3, 4, 7, 9, 3, 11, 19, 10, 5, 15]);

  • 桶排序
function bucketSort(nums: number[]) {
  const [min, max] = _getMinOrMax(nums);
  const gap = Math.ceil(Math.sqrt(max - min + 1));
  let buckets = new Array(gap).fill("").map(() => []);
  for (let i = 0; i < nums.length; i++) {
    let j = 1;
    while (nums[i] > j * gap + min) {
      j++;
    }
    j--;
    const bk = buckets[j];
    bk.push(nums[i]);
    for (let x = bk.length - 1; x > 0; x--) {
      if (bk[x] < bk[x - 1]) {
        _swap(bk, x, x - 1);
      } else {
        break;
      }
    }
  }
  return buckets.flat();
}

const bucketRes = bucketSort([
  3, 44, 7, 100, 9, 0, 333, 66, 37, 222, 305, 604, 3, 8, 4,
]);
  • 基数排序
function radixSort(nums: number[]) {
  let max = -Infinity;
  nums.forEach((item) => (max = item > max ? item : max));
  let di = 1;
  while (di <= max) {
    const buckets = new Array(10).fill("").map(() => []);
    for (let i = 0; i < nums.length; i++) {
      const key = Math.floor((nums[i] % (di * 10)) / di);
      buckets[key].push(nums[i]);
    }
    nums = buckets.flat();
    di = di * 10;
  }
  return nums;
}

const radixRes = radixSort([
  3, 44, 7, 100, 9, 0, 333, 66, 37, 222, 305, 604, 3, 8, 4,
]);

- 其他工具函数

function _swap(nums: number[], i: number, j: number) {
  const temp = nums[i];
  nums[i] = nums[j];
  nums[j] = temp;
}

function _getMinOrMax(nums: number[]) {
  let min = Infinity,
    max = -Infinity;
  nums.forEach((item) => {
    min = item > min ? min : item;
    max = item > max ? item : max;
  });
  return [min, max];
}