Skip to content

排序

简单排序

冒泡排序

function sort(arr) {
  let hasChanged = true; // 如果没发生换位,说明已经排好序
  for(let i = 0; hasChanged && i < arr.length - 1; i++) {
    hasChanged = false;

    for(let j = 0; j < arr.length - 1; j++) {
      if (arr[j] > arr[j + 1]) {
        swap(arr, j, j + 1);
        hasChanged = true;
      }
    }
  }
}

function swap(arr, i, j) {
  let temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp
}
  • 空间复杂度 O(1)
  • 时间复杂度 O(n^2),最好情况 O(n)

插入排序

function sort(arr) {
  for(let i = 0; i < arr.length; i++) {
    let current = arr[i];

    let j;
    for(j = i - 1; j >= 0 && arr[j] > current; j--) {
      arr[j + 1] = arr[j]
    }

    arr[j + 1] = current;
  }
}
  • 空间复杂度 O(1)
  • 时间复杂度 O(n^2)

常考排序

归并排序

function sort(arr, low, high) {
  if (low >= high) {
    return;
  }

  const middle = low + Math.floor((high - low) / 2);

  sort(arr, low, middle);
  sort(arr, middle + 1, high);

  merge(arr, low, middle, high);
}

function merge(arr, low, middle, high) {
  let arrCopy = [...arr];

  let k = low;
  let i = low;
  let j = middle + 1;

  while(k <= high) {
    if (i > middle) { // 左半边已遍历完
      arr[k++] = arrCopy[j++];
    } else if (j > high) { // 右半边已遍历完
      arr[k++] = arrCopy[i++];
    } esle if (arrCopy[i] <= arrCopy[j]) {
      arr[k++] = arrCopy[i++];
    } else {
      arr[k++] = arrCopy[j++];
    }
  }
}
  • 时间复杂度 T(n) = 2 * T(n / 2) + O(n), 结果为 O(nlogn)
  • 空间复杂度 O(n)

快速排序

function sort(arr, low, high) {
  if (low >= high) {
    return;
  }

  let p = partion(arr, low, high);

  sort(arr, low, p);
  sort(arr, p + 1, high);
}

function partion(arr, low, high) {
  let pivot = low; // 支点
  let current = arr[pivot];

  for (let i = low + 1; i <= high; i++) {
    if (arr[i] < current) {
      arr[pivot++] = arr[i];
      arr[i] = arr[pivot];
    }
  }
  arr[pivot] = current;

  return pivot;
}
  • 时间复杂度与基准值的挑选有关,最好情况 T(n) = 2 * T(n / 2) + O(n), 最坏情况为 O(n^2)
  • 平均时间复杂度为 O(nlogn)
  • 空间复杂度 O(logn),每次递归只需要开辟 O(1) 的空间来完成交换,递归深度为 O(logn)

拓扑排序

  • 表示因果关系
  • 前提
    • 必须是有向图
    • 图里没有环
function sort() {
  const q = new LinkedList();

  for(let v = 0; v < V; v++) {
    if (indegree[v] === 0) { // 入度为 0 的顶点进入队列
      q.add(v);
    }
  }

  while(!q.isEmpty()) {
    let v = q.poll();
    print(v);

    for(let u = 0; u < adj[v].length; u++) {
      indegree[u]--;
      if (indegree[u] === 0) {
        q.add(u);
      }
    }
  }
}
  • 时间复杂度 O(n)

其他排序

堆排序

桶排序