/** * 使用堆排序算法,将目标数组从小到大排列 */ voidHeapSort(int A[], int len){ BuildMaxHeap(A, len); // 初始建堆 for (i = len; i > 1; i--) { // n - 1 趟的交换和建堆过程 // 输出堆顶元素(和堆底元素交换) int tmp = A[i]; A[i] = A[1]; A[1] = tmp;
// 整理,把剩余的 i - 1 个元素整理成堆 AdjustDown(A, 1, i - 1); } // for } /** * 建立大根堆,注意 A[0] 中不存储元素,实际存储从 A[1] 开始 */ voidBuildMaxHeap(int A[], int len){ for (int i = len/2; i > 0; i--) { // 从 len/2 ~ 1,反复调整堆 AdjustDown(A, i, len); } } /** * 将元素 k 向下进行调整 */ voidAdjustDown(int A[], int k, int len){ A[0] = A[k]; // A[0] 暂存 for (i = 2 * k; i <= len; i*= 2) { // 沿 key 较大的子结点向下筛选 if (i < len && A[i] < A[i + 1]) { // 取 key 较大的子结点的下标 i++; } if (A[0] >= A[i]) { // 筛选结束 break; } else { A[k] = A[i]; // 将 A[i] 调整到双亲结点上 k = i; // 修改 k 值,以便继续向下筛选 } } // for A[k] = A[0]; // 被筛选结点的值放入最终位置 }
1 2 3 4 5 6 7 8 9 10 11 12 13
/** * 参数 k 为向上调整的结点,也为堆的元素个数 */ voidAdjustUp(int A[], int k){ A[0] = A[k]; int i = k / 2; // 若结点值大于双亲结点,则将双亲结点向下调,并继续向上比较 while (i > 0 && A[i] < A[0]) { A[k] = A[i]; k = i; i = k / 2; } // while A[k] = A[0]; }
/** * 将长度为 n 的数组逆序 */ voidreverse(intarray[], int n){ int i = 0; int j = n - 1; while (i < j) { int tmp = array[i]; array[i] = array[j]; array[j] = tmp;
i++; j--; } } /** * 将含有 n 个元素的数组向左循环移位 i 个位置 */ voidexchange(intarray[], int n, int i){ reverse(array, i); reverse(array + i, n - i); reverse(array, n); } voidMerge(intarray[], int low, int mid, int high){ int i = low; int j = mid + 1; while (i < j && j <= high) { int step = 0; while (i < j && array[i] <= array[j]) { i++; } while (j <= high && array[j] <= array[i]) { j++; step++; } // array + i 为子数组首地址,j - i 为子数组元素个数,j - i - step 为左循环移位的个数 exchange(array + i, j - i, j - i - step); i += step; } }