#include <stdio.h>
#include <stdlib.h>
void swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
void heapify(int arr[],int n,int i)
{
int low=i;
int lchild=i*2+1;
int rchild=i*2+2;
if(lchild<n&&arr[lchild]<arr[low])
low=lchild;
if(rchild<n&&arr[rchild]<arr[low])
low=rchild;
if(low!=i)
swap(&arr[i],&arr[low]);
heapify(arr,n,low);
}
void B_heap(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);
}
}
int main()
{
int arr[8]={6,11,12,16,14,15,10};
int n=7;
B_heap(arr,n);
for(int i=0;i<n;i++)
{
printf("%d\n",arr[i]);
}
return 0;
}
代码有些地方被覆盖了 麻烦重新贴一下
这里错了
void heapify(int arr[],int n,int i)
{
int low=i;
int lchild=i*2+1;
int rchild=i*2+2;
if(lchild<n&&arr[lchild]<arr[low])
low=lchild;
if(rchild<n&&arr[rchild]<arr[low])
low=rchild;
if(low!=i) { //少了大括号, 递归子堆
swap(&arr[i],&arr[low]);
heapify(arr,n,low);
}
}
帮你写下,支持大量数据
/*④ 生成500个在[200, 10000]之间的整数保存数组A中,以此数组元素作为关键字,
采用堆排序算法按非递减方式进行排序,给出操作的结果及相应的操作次数;*/
#include <stdio.h>
#include<stdlib.h>
#define numOfd 5
typedef int data;//类型改名
typedef struct DataType
{
data key;
}DataType;
//堆排序算法
//(1)最大堆调整
void CreatHeap(DataType a[],int n,int h)
{
//调整非叶节点a[h]使之满足最大堆,n为数组a的元素个数,h为:(n-2)/2
int i,j,flag;
DataType temp;
i=h; //i为要建堆的二叉树根结点下标
j=2*i+1; //j为i的左孩子结点的下标
temp=a[i];
flag=0;
//沿左右孩子中值较大者重复向下筛选
while(j<n&&flag!=1){
//寻找左右孩子结点中的较大者,j为其下标
if(j<n-1&&a[j].key<a[j+1].key)j++;//这里完成了对于根左右孩子结点值的比较
if(temp.key>a[j].key)
flag=1; //标记结束筛选条件
else{ //否则把a[j]上移
a[i]=a[j];
i=j;
j=2*i+1;
}
}
a[i]=temp; //把最初的a[i]赋值给最后的a[j]
}
//(2)创建最大堆
void InitCreatHeap(DataType a[],int n)
{
//把a[0]~a[n-1]初始化创建为最大堆
int i;
for(i=(n-2)/2;i>=0;i--)
{
CreatHeap(a,n,i);
}
}
//(3)堆排序
void HeapSort(DataType a[],int n)
{
int i;
DataType temp;
InitCreatHeap(a,n); //初始化创建最大堆
for(i=n-1;i>0;i--)
{
temp=a[0];
a[0]=a[i];
a[i]=temp;
CreatHeap(a,i,0); //调整根结点满足最大堆,只需要对根结点进行最大堆化,其它的已满足最大堆
}
}
//生成由随机数组成的数组
DataType *rand_array(int number,int min,int max)
{
int i;
DataType *a=NULL;
a=(DataType *)malloc(number*sizeof(int));
for(i=0;i<number;i++)
{
a[i].key=rand()%(max-min+1)+min;
}
return a;
}
//输出排序后的结果
void print(DataType a[],int numOfA)
{
int i;
for(i=0;i<numOfA;i++)
{
if(i%20==0){printf("\n");}
printf("%d ",a[i].key);
}
}
int main(){
DataType *c=rand_array(500,200,10000);
printf("排序前:\n");
print(c,500);
HeapSort(c,500);
printf("\n");
printf("\n堆排序后:\n");
print(c,500);
}
你的算法是不对的,另外这个递归函数写错了,递归函数里面没有根据条件进行return,结尾又接了递归函数,导致无限递归,所以你的界面什么都不显示,程序一直在无限递归了。
void heapify(int arr[],int n,int i)
{
int low=i;
int lchild=i*2+1;
int rchild=i*2+2;
if(lchild<n&&arr[lchild]<arr[low])
low=lchild;
if(rchild<n&&arr[rchild]<arr[low])
low=rchild;
if(low!=i)
swap(&arr[i],&arr[low]);
heapify(arr,n,low);
}
把错误信息贴一下,才好分析问题原因啊
应该把 swap(&arr[0],&arr[i]) 里的&去掉吧
#include <stdio.h>
#include <stdlib.h>
#define MAXITEM 100
void printArray(int arr[], int n) {
int i;
for (i = 1; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
/*
生成大根堆
R:待排序数组
v:下标
n:最后一个下标
*/
void Heapify(int R[MAXITEM], int v, int n) {
int i, j;
i = v;
j = i * 2; // R[i]的左子节点
R[0] = R[i]; // 暂存父节点的值,方便最终替换时赋值
while (j <= n) {
// 先判断左右子节点的大小,再与父节点进行比较
// 其中 j<n 说明他存在兄弟节点
if (j<n && R[j]<R[j+1])
{
j++; // 右节点比当左子节点大,则用右节点与父节点比较
}
// 如果父节点的值小于子节点值
if (R[i] < R[j]) {
R[i] = R[j]; // 替换父节点的值
i = j; // 将要比较的父节点变成当前子节点
j = 2 * i; // 将要比较的子节点变成当前子节点的子节点
}
else { // 如果父节点不小于则直接退出循环,因为根堆是从下往上构建的,如果父节点不需要替换,子节点自然不用再重新替换
j = n + 1;
}
R[i] = R[0]; // 将父节点的值赋值到当前节点
}
}
/*
堆排序算法
本算法舍弃了数组下标0的空间,直接从下标1开始排序
*/
void HeapSort(int R[MAXITEM], int n) {
int i;
// 将数组先变成一个大根堆
// n/2 一定是最后一个非叶子节点,其前面的都是非叶子节点
for (i = n / 2; i >= 1; i--) {
Heapify(R, i, n);
}
// 大根堆只需要保证其父节点的值大于左右子节点的值即可,无需排列的很整齐
printf("初始构建大根堆:");
printArray(R, n + 1);
// 开始排序,将根节点移除在外,然后用最后一个叶子节点代替根节点
for (i = n; i > 1; i--)
{
// 将根节点与最后一个叶子节点交换位置,R[0]作为临时空间存在,用于存放要交换的数据
R[0] = R[i];
R[i] = R[1];
R[1] = R[0];
// 将最后一个数(也就是根节点)排除在外后再进行构建堆操作
Heapify(R, 1, i - 1);
printf("第%d次排序:",n-i+1);
printArray(R, n + 1);
}
}
int main() {
int arr[] = {0, 7, 10, 13, 15, 4, 20, 19, 8 };
// 这里我舍弃了下标0的空间,从下标1开始排序
HeapSort(arr, sizeof(arr)/sizeof(int)-1);
printf("最终结果:");
printArray(arr, sizeof(arr) / sizeof(int));
}