Heap-Sort

#include <stdio.h>

void swap  (int* a, int* b)  {*a = *a ^ *b; *b = *a ^ *b; *a = *a ^ *b;}
int  parent(int i) {return (i - 1) / 2;}
int  left  (int i) {return  2 * i  + 1;}
int  right (int i) {return  2 * i  + 2;}

void maxHeapify (int A[], int i, int heapSize)
{
    int l = left(i), r = right(i), largest;

    if ( (l < heapSize) && (A[l] > A[i]) )
        largest = l;
    else
        largest = i; 
    if ( (r < heapSize) && (A[r] > A[largest]) )
        largest = r;

    if (largest != i) {
        swap(&A[i], &A[largest]);
        maxHeapify (A, largest, heapSize);
    }    
}

void buildMaxHeap (int A[], int heapSize)
{
    int i;
    for (i = (heapSize - 1) / 2; i >= 0; --i)
        maxHeapify(A, i, heapSize);
}

void heapSort(int A[], int heapSize)
{
    int i;

    buildMaxHeap(A, heapSize);
    for (i = heapSize - 1; i > 0; --i)
    {
        swap(&A[0], &A[i]);
        --heapSize;
        maxHeapify(A, 0, heapSize);
    }
}

main()
{
    int i;
    int A[]  = {8, 7, 3, 16, 10, 9, 14, 2, 1, 4};
    int size = sizeof(A) / sizeof(int);

    printf("Before heapSort: ");
    for (i = 0; i < size; ++i)
        printf("%2d ", A[i]);
    printf("\n");

    heapSort(A, size);

    printf("After  heapSort: ");
    for (i = 0; i < size; ++i)
        printf("%2d ", A[i]);
    printf("\n");
}

标题基于Python的自主学习系统后端设计与实现AI更换标题第1章引言介绍自主学习系统的研究背景、意义、现状以及本文的研究方法和创新点。1.1研究背景与意义阐述自主学习系统在教育技术领域的重要性和应用价值。1.2国内外研究现状分析国内外在自主学习系统后端技术方面的研究进展。1.3研究方法与创新点概述本文采用Python技术栈的设计方法和系统创新点。第2章相关理论与技术总结自主学习系统后端开发的相关理论和技术基础。2.1自主学习系统理论阐述自主学习系统的定义、特征和理论基础。2.2Python后端技术栈介绍DjangoFlask等Python后端框架及其适用场景。2.3数据库技术讨论关系型和非关系型数据库在系统中的应用方案。第3章系统设计与实现详细介绍自主学习系统后端的设计方案和实现过程。3.1系统架构设计提出基于微服务的系统架构设计方案。3.2核心模块设计详细说明用户管理、学习资源管理、进度跟踪等核心模块设计。3.3关键技术实现阐述个性化推荐算法、学习行为分析等关键技术的实现。第4章系统测试与评估对系统进行功能测试和性能评估。4.1测试环境与方法介绍测试环境配置和采用的测试方法。4.2功能测试结果展示各功能模块的测试结果和问题修复情况。4.3性能评估分析分析系统在高并发等场景下的性能表现。第5章结论与展望总结研究成果并提出未来改进方向。5.1研究结论概括系统设计的主要成果和技术创新。5.2未来展望指出系统局限性并提出后续优化方向。
<think>根据用户要求,我们需要使用最小堆来维护最大的1000个数字。主要思路是: 1. 初始化一个大小为1000的最小堆。 2. 首先读取前1000个数字,构建最小堆。 3. 对于后续的每个数字,如果它大于堆顶元素(即当前堆中最小的元素),则替换堆顶元素,然后调整堆,以保持最小堆的性质。 4. 当所有数字处理完毕后,堆中保存的就是最大的1000个数字。 5. 最后,我们可以对堆进行排序(降序)然后输出,或者直接输出(但堆中元素并不是有序的,所以通常需要排序后输出)。 注意:如果总数字个数n小于1000,则直接构建最小堆,然后排序输出即可。 根据之前提供的代码,我们已经有了构建最小堆和调整堆的函数。现在需要编写主函数(main)来读取输入并处理。 输入格式:第一行是数字的总个数n,然后依次是n个整数。 示例输入: 5 1 2 3 4 5 要求输出最大的1000个数字(这里n=5,所以输出最大的5个数字,按降序排列)。 步骤: 1. 读取n。 2. 如果n<=1000,则读取所有数字,然后构建最小堆,再堆排序(降序)输出。 3. 如果n>1000,则先读取前1000个数字构建最小堆,然后对于剩下的n-1000个数字,逐个判断:如果大于堆顶,则替换堆顶并调整堆。 4. 最后,将堆中的1000个元素进行堆排序(降序)并输出。 注意:堆排序(降序)使用最小堆实现的方法是:不断将堆顶(最小)与当前堆的最后一个元素交换,然后调整剩余堆(大小减一),这样最后得到的数组是从大到小排列的。 在之前的代码中,我们已经有了: adjust_min_heap: 调整最小堆(下沉操作) build_min_heap: 构建最小堆 heap_sort_descending: 使用最小堆进行降序排序(即堆排序) 因此,我们只需要在主函数中按照上述步骤调用即可。 但是注意:在堆排序函数中,我们是对整个堆数组进行排序,排序后堆结构就不存在了,但这里我们只需要输出排序后的结果。 下面我们根据上述思路编写主函数。注意,我们假设堆的大小为1000(宏定义HEAP_SIZE)。 注意:由于堆排序(降序)会改变堆数组,所以我们在处理完所有数据后再进行排序输出。 代码实现如下:</think>根据最小堆原理实现获取最大1000个数字的完整C语言程序如下: ```c #include <stdio.h> #include <stdlib.h> #define HEAP_SIZE 1000 // 最小堆调整(下沉操作) void adjust_min_heap(int *heap, int i, int len) { int temp = heap[i]; int j = 2 * i + 1; // 左子节点索引 while (j < len) { // 选择较小的子节点 if (j + 1 < len && heap[j] > heap[j + 1]) { j++; } // 若子节点更小则下沉 if (temp > heap[j]) { heap[i] = heap[j]; i = j; j = 2 * i + 1; } else { break; } } heap[i] = temp; } // 构建最小堆 void build_min_heap(int *heap, int len) { // 从最后一个非叶子节点开始调整 for (int i = len / 2 - 1; i >= 0; i--) { adjust_min_heap(heap, i, len); } } // 堆排序(最小堆得到降序结果) void heap_sort_descending(int *heap, int len) { for (int i = len - 1; i > 0; i--) { // 交换堆顶与当前末尾元素 int temp = heap[0]; heap[0] = heap[i]; heap[i] = temp; // 调整剩余堆 adjust_min_heap(heap, 0, i); } } int main() { int n; printf("请输入数字总数: "); scanf("%d", &n); int *heap = (int *)malloc(HEAP_SIZE * sizeof(int)); if (!heap) { perror("内存分配失败"); return 1; } // 情况1:元素总数≤1000 if (n <= HEAP_SIZE) { printf("请输入%d个数字: ", n); for (int i = 0; i < n; i++) { scanf("%d", &heap[i]); } build_min_heap(heap, n); heap_sort_descending(heap, n); printf("\n最大的%d个数字(降序): ", n); for (int i = 0; i < n; i++) { printf("%d ", heap[i]); } free(heap); return 0; } // 情况2:元素总数>1000 printf("请输入%d个数字(前1000个用于初始化堆): ", n); for (int i = 0; i < HEAP_SIZE; i++) { scanf("%d", &heap[i]); } // 构建初始最小堆 build_min_heap(heap, HEAP_SIZE); // 处理剩余元素 int num; for (int i = 0; i < n - HEAP_SIZE; i++) { scanf("%d", &num); if (num > heap[0]) { heap[0] = num; // 替换堆顶 adjust_min_heap(heap, 0, HEAP_SIZE); // 调整堆 } } // 堆排序得到降序结果 heap_sort_descending(heap, HEAP_SIZE); // 输出结果 printf("\n最大的1000个数字(降序):\n"); for (int i = 0; i < HEAP_SIZE; i++) { printf("%d ", heap[i]); if ((i + 1) % 20 == 0) printf("\n"); // 每行输出20个 } free(heap); return 0; } ``` ### 程序说明 1. **核心数据结构**: - 使用最小堆维护当前最大的1000个数字 - 堆顶始终是当前1000个数字中的最小值 2. **算法流程**: ```mermaid graph TD A[开始] --> B[读取总数字数n] B --> C{n <= 1000?} C -->|是| D[读取所有数字] D --> E[构建最小堆] E --> F[堆排序降序输出] C -->|否| G[读取前1000个数字] G --> H[构建初始最小堆] H --> I[处理剩余数字] I --> J{新数字 > 堆顶?} J -->|是| K[替换堆顶并调整] J -->|否| L[丢弃该数字] K --> M[继续处理] L --> M M --> N{处理完所有数字?} N -->|否| I N -->|是| O[堆排序降序输出] ``` 3. **关键操作**: - **堆调整**:时间复杂度 $O(\log k)$,其中 $k=1000$ - **堆构建**:时间复杂度 $O(k)$ - **堆排序**:时间复杂度 $O(k \log k)$ - **总体时间复杂度**:$O(n \log k)$,优于完整排序的 $O(n \log n)$ 4. **空间效率**: - 固定使用 $O(k)$ 空间($k=1000$) - 适用于处理海量数据(如GB级数据流) ### 使用示例 **输入示例1(n=5)**: ``` 请输入数字总数: 5 请输入5个数字: 5 3 8 1 6 ``` **输出示例1**: ``` 最大的5个数字(降序): 8 6 5 3 1 ``` **输入示例2(n=2000)**: ``` 请输入数字总数: 2000 请输入2000个数字(前1000个用于初始化堆): [2000个随机数] ``` **输出示例2**: ``` 最大的1000个数字(降序): [按降序排列的1000个最大数字,每行20个] ``` ### 性能优化建议 1. **内存映射文件**:处理超大规模数据时使用`mmap` 2. **多线程处理**:将数据分块并行处理 3. **堆调整优化**:使用自底向上的堆调整算法 4. **增量更新**:适用于实时数据流场景
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值