欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > hnust 1817 算法10-10,10-11:堆排序

hnust 1817 算法10-10,10-11:堆排序

2024/10/23 21:40:39 来源:https://blog.csdn.net/weixin_50950742/article/details/139944479  浏览:    关键词:hnust 1817 算法10-10,10-11:堆排序

hnust 1817 算法10-10,10-11:堆排序

题目描述
堆排序是一种利用堆结构进行排序的方法,它只需要一个记录大小的辅助空间,每个待排序的记录仅需要占用一个存储空间。
首先建立小根堆或大根堆,然后通过利用堆的性质即堆顶的元素是最小或最大值,从而依次得出每一个元素的位置。
堆排序的算法可以描述如下:
在这里插入图片描述

在本题中,读入一串整数,将其使用以上描述的堆排序的方法从小到大排序,并输出。

输入
输入的第一行包含1个正整数n,表示共有n个整数需要参与排序。其中n不超过100000。
第二行包含n个用空格隔开的正整数,表示n个需要排序的整数。
输出
只有1行,包含n个整数,表示从小到大排序完毕的所有整数。
请在每个整数后输出一个空格,并请注意行尾输出换行。
样例输入 Copy
10
2 8 4 6 1 10 7 3 5 9
样例输出 Copy
1 2 3 4 5 6 7 8 9 10
提示
在本题中,需要按照题目描述中的算法完成堆排序的算法。
堆排序对于元素数较多的情况是非常有效的。通过对算法的分析,不难发现在建立含有n个元素的堆时,总共进行的关键字比较次数不会超过4n,且n个节点的堆深度是log2n数量级的。因此,堆排序在最坏情况下的时间复杂度是O(nlog2n),相对于快速排序,堆排序具有同样的时间复杂度级别,但是其不会退化。堆排序较快速排序的劣势是其常数相对较大。

解题过程

堆排序是一种利用堆数据结构的排序算法,分为两个阶段:建立堆和堆排序。

下面是对代码的详细解析:

  1. 头文件

    • 包含 <stdio.h><string> 头文件,分别提供输入输出功能和字符串操作。
  2. 命名空间

    • 使用 using namespace std; 来避免在标准库类型和函数前加 std::
  3. 常量定义

    • maxn 定义了数组 heap 的最大长度。
  4. 全局数组 heap

    • 用作堆数据结构的存储空间。
  5. 交换函数 swap

    • 通过引用传递参数,实现两个整数的交换。
  6. 下沉调整函数 downAdjust

    • 从指定位置 low 开始,到 high 结束,对堆进行下沉调整,确保堆的性质。
  7. 创建堆函数 createheap

    • n/2 开始,向下对每个节点调用 downAdjust,以构建最小堆。
  8. 堆排序函数 heapsort

    • 首先调用 createheap 创建最小堆。
    • 然后交换堆顶元素(最小元素)和最后一个元素,减少堆的大小,并下沉调整堆。
  9. 主函数 main

    • 读取整数 n,直到输入结束或 n 为0。
    • 读取 n 个整数,存储到 heap 数组中。
    • 调用 heapsort 函数进行堆排序。
    • 打印排序后的数组,每个数字后跟一个空格。
  10. 程序结束

    • 输入结束后,程序返回0,表示正常结束。

代码逻辑分析

  • 这段代码首先读取要排序的数组长度 n,然后读取 n 个整数,存储到 heap 数组中。
  • 使用 heapsort 函数对数组进行排序,该函数首先创建一个最小堆,然后通过交换和下沉调整将元素按顺序输出。

潜在问题

  • 代码中使用了 getchar() 来读取输入中的换行符,这可能会导致在某些输入情况下出现意外行为。

改进建议

  • 考虑使用 std::cinstd::getline 替代 scanfgetchar() 来处理输入,以提高代码的可读性和健壮性。
  • 可以添加对输入数据有效性的检查,确保读取的是有效的整数。
  • 考虑使用更现代的C++特性,如 std::vector,以提高代码的灵活性。

部分代码

代码如下( 交换):

void swap(int &a,int &b){int temp;temp=a;a=b;b=temp;
}

代码如下( 对堆进行下沉调整):

void downAdjust(int low,int high){int i=low;int j=2*i;while(j<=high){if(j+1<=high&&heap[j+1]<heap[j])j++;if(heap[j]<heap[i]){swap(heap[i],heap[j]);i=j;j=2*i;}else{break;}}
} 

代码如下( 创建堆):

void createheap(int n){for(int i=n/2;i>=1;i--){downAdjust(i,n);}
}

代码如下(排序):

void heapsort(int n){createheap(n);for(int i=n;i>1;i--){swap(heap[i],heap[1]);downAdjust(1,i-1);}
}

AC代码

#include<stdio.h>
#include<string>
#include<string.h>
using namespace std;
const int maxn=100000;
int heap[maxn];
void swap(int &a,int &b){int temp;temp=a;a=b;b=temp;
}
void downAdjust(int low,int high){int i=low;int j=2*i;while(j<=high){if(j+1<=high&&heap[j+1]<heap[j])j++;if(heap[j]<heap[i]){swap(heap[i],heap[j]);i=j;j=2*i;}else{break;}}
} 
void createheap(int n){for(int i=n/2;i>=1;i--){downAdjust(i,n);}
}
void heapsort(int n){createheap(n);for(int i=n;i>1;i--){swap(heap[i],heap[1]);downAdjust(1,i-1);}
}
int main()
{int n;while(scanf("%d",&n)!=EOF&&n!=0){getchar();for(int i=1;i<=n;i++){scanf("%d",&heap[i]);getchar();}heapsort(n);for(int i=n;i>0;i--){printf("%d ",heap[i]);}printf("\n");}return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com