「已注销」 2024-12-11 13:56 采纳率: 55.6%
浏览 17
已结题

数据结构C语言代码F求解


#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 heapSort(int arr[], int n) {
    // 构建堆(从最后一个非叶子节点开始)
    for (int i = n / 2 - 1; i >= 0; i--)
        heapify(arr, n, i);

    // 一个个从堆中取出元素
    for (int i = n - 1; i >= 0; i--) {
        // 将当前的根节点移到数组末尾
        swap(&arr[0], &arr[i]);
        // 调用 heapify 函数来减少堆的大小并重新堆化
        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 n;
    scanf("%d", &n);
    int arr[n];
    for (int i = 0; i < n; i++)
        scanf("%d", &arr[i]);

    // 打印每一轮调整的中间过程结果
    for (int i = 0; i < n; i++) {
        heapSort(arr, i + 1);
        printArray(arr, n);
    }

    // 打印最终排序结果
    heapSort(arr, n);
    printArray(arr, n);
    return 0;
}

输出结果为

img


这个代码究竟哪里错了,为什么结果不符合以下例子Sample Input
10
2 8 4 6 1 10 7 3 5 9
Sample Output
1 9 7 6 8 4 2 3 5 10
5 8 7 6 1 4 2 3 9 10
3 6 7 5 1 4 2 8 9 10
2 6 4 5 1 3 7 8 9 10
3 5 4 2 1 6 7 8 9 10
1 3 4 2 5 6 7 8 9 10
2 3 1 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10

  • 写回答

1条回答 默认 最新

  • 越重天 新星创作者: Java技术领域 2024-12-13 12:18
    关注

    本答案参考多次询问ChatGPT-3.5后选择的最佳回答,若是满意,还请采纳,谢谢。

    1. 问题分析
      • 这段代码的目的是实现堆排序算法。但是,在main函数中的循环部分存在逻辑错误。
      • main函数中,每次调用heapSort函数时,传入的数组大小是递增的(从1到n),并且每次都打印整个数组。这样做不符合堆排序的正常逻辑,因为每次都在对一个未完全排序的子数组进行重新排序并打印整个数组,而不是只对完整的数组进行一次堆排序并逐步展示中间过程。
    2. 修正后的代码如下
    #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 heapSort(int arr[], int n) {
        for (int i = n / 2 - 1; i >= 0; i--)
            heapify(arr, n, i);
        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 n;
        scanf("%d", &n);
        int arr[n];
        for (int i = 0; i < n; i++)
            scanf("%d", &arr[i]);
        // 只进行一次堆排序
        heapSort(arr, n);
        // 打印中间过程(这里可以根据需求调整,比如每交换一次就打印一次)
        for (int i = 0; i < n; i++) {
            printArray(arr, n);
        }
        return 0;
    }
    
    1. 解释修正部分
      • 在原代码中,main函数中的循环for (int i = 0; i < n; i++)每次都对不同大小的子数组进行堆排序并打印整个数组,这是错误的。
      • 修正后的代码首先对整个数组进行一次堆排序(heapSort(arr, n)),然后可以根据需求在排序过程中打印中间结果。这里简单地在排序后的数组上循环打印每个元素,也可以在heapSort函数内部添加更多的打印语句来展示更详细的中间过程,比如在每次交换元素后打印数组。
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 12月21日
  • 已采纳回答 12月13日
  • 创建了问题 12月11日