```c #include <stdio.h> // 交换两个元素的值 void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } // 调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上) void heapify(int arr[], int n, int i) { int largest = i; // 初始化最大为根节点 int left = 2 * i + 1; // 左子节点 int right = 2 * i + 2; // 右子节点 // 如果左子节点大于根节点 if (left < n && arr[left] > arr[largest]) { largest = left; } // 如果右子节点大于当前最大的节点 if (right < n && arr[right] > arr[largest]) { largest = right; } // 如果最大的不是根节点,交换它们 if (largest != i) { swap(&arr[i], &arr[largest]); // 递归地调整受影响的子树 heapify(arr, n, largest); } } // 构建大顶堆 void buildHeap(int arr[], int n) { // 从最后一个非叶子节点开始向上调整 for (int i = n / 2 - 1; i >= 0; i--) { heapify(arr, n, i); } } // 堆排序 void heapSort(int arr[], int n) { // 构建大顶堆 buildHeap(arr, n); // 一个个从堆顶取出元素 for (int i = n - 1; i > 0; i--) { // 将当前根节点(最大值)移到数组末尾 swap(&arr[0], &arr[i]); // 重新调整剩余部分,使之成为大顶堆 heapify(arr, i, 0); } } // 打印数组 void printArray(int arr[], int n) { for (int i = 0; i < n; ++i) { printf("%d ", arr[i]); } printf("\n"); } int main() { int arr[] = {12, 11, 13, 5, 6, 7}; int n = sizeof(arr) / sizeof(arr[0]); printf("原始数组: \n"); printArray(arr, n); heapSort(arr, n); printf("排序后数组: \n"); printArray(arr, n); } ``` ### 额外需要注意的逻辑点 1. **边界条件**:确保在 `heapify` 函数中正确处理边界条件,避免数组越界。 2. **递归调用**:在 `heapify` 中递归调用时,确保每次调用都传递正确的参数,特别是子树的大小。 3. **初始化**:在 `buildHeap` 函数中,从最后一个非叶子节点开始向上调整,确保整个数组形成一个大顶堆。 [2024-11-23 16:52:14 | AI写代码神器 | 674点数解答]