【Heap Sort】堆排的三种写法

方法一:


复杂度分析

  • 时间复杂度: O ( ) O()
  • 空间复杂度: O ( ) O()

方法二:


复杂度分析

  • 时间复杂度: O ( ) O()
  • 空间复杂度: O ( ) O()

方法三:原地堆排

  • 从最后一个非叶子结点进行堆化。
  • 然后堆化子数组。
    • 因为第一次堆化完数组,最大元素出现在堆头,所以交换后堆头与数组最后一个元素后,最大元素被放置在了数组末尾,末尾之前的序列已不再是合法的堆结构,需要重新堆化子数组 [0, n-1]
//堆化子数组
public void heapSort03(int[] arr, int N) {
  // 堆化
  for (int i = N / 2 - 1; i >= 0; i--) {
    sift_down(arr, N, i);
  }
  // 堆化子数组
  for (int i = N - 1; i >= 0; i--) {
    // 交换后,最大的元素原在arr[0],此时末尾元素才是最大,故需要重新堆化子数组[0,n-2]
    swap(arr, i, 0);
    sift_down(arr, i, 0);
  }
}

private void sift_down(int[] arr, int N, int k) {
  int t = 2 * k + 1;
  while (t < N) {
    int r = 2 * k + 2;
    // 取二孩子的最大者
    if (r < N && arr[r] > arr[t])
      t = r;
    if (arr[k] >= arr[t])
      break;

    swap(arr, k, t);
    k = t;
  }
}
private static void swap (int[] arr, int l, int r) {
  int temp = arr[l];
  arr[l] = arr[r];
  arr[r] = temp;
}

复杂度分析

  • 时间复杂度: O ( ) O()
  • 空间复杂度: O ( ) O()
发布了419 篇原创文章 · 获赞 94 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_43539599/article/details/104432133