C语言如何完整复制堆数组?堆排序场景下临时堆拷贝实现问题
问题解决方法
核心问题:堆复制写法错误
你原本的两种复制方案都不符合C语言的语法规则:
- C语言中数组名是地址常量,不能直接被赋值,因此
copyheap = maxheap会直接编译报错 strcpy是专门用于复制以\0结尾的字符串的函数,不适合结构体数组的复制操作,会出现内存访问异常、复制结果错误的问题
正确复制方案
你的element结构体没有指针成员,内存布局连续,直接使用内存拷贝函数memcpy即可完成堆的完整复制,写法如下:
// 复制minheap到copyheap,有效元素个数为minn(你的堆从下标1开始使用,因此复制范围是0~minn共minn+1个元素) memcpy(copyheap, minheap, sizeof(element) * (minn + 1)); // 复制maxheap到copyheap同理 memcpy(copyheap, maxheap, sizeof(element) * (maxn + 1));
你已经引入了<string.h>头文件,无需额外引入依赖。
其他需要修复的代码bug
改完复制逻辑后如果仍然无法正常运行,还需要修改以下问题:
- 文件指针未重置
你第一个while循环遍历完整个文件统计totalnum后,文件指针已经处于文件末尾,第二个while循环无法读取到任何内容。在第一个循环结束后添加rewind(fp);即可将文件指针重置到开头。 - deleteminheap逻辑错误
删除最小堆节点的逻辑中,判断终止条件的变量用错,将:
if(item.key<=copyheap[child].key)break;
修改为:
if(temp.key<=copyheap[child].key)break;
和deletemaxheap的判断逻辑保持一致,用待上浮的尾节点值和子节点比较即可。
3. feof使用不规范feof是读取操作失败后才会置位的标记,直接用while(!feof(fp))会多统计一次无效的读取次数,统计totalnum的循环可以修改为:
while(fscanf(fp, "%s", arr) == 1) { totalnum++; }
内容的提问来源于stack exchange,提问作者chae yeon
相关产品推荐
相关产品推荐

