C语言 堆排序 数据结构

c语言堆排序,输出不了结果

#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);
    }
}

帮你写下,支持大量数据

img

/*④ 生成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);     
}

把错误信息贴一下,才好分析问题原因啊

img

应该把 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));
}