数据结构之大顶堆,小顶堆和堆排序

本文解决的问题是:

随机产生20个数,构建大顶堆,小顶堆,然后进行堆排序。

实现代码如下:

/*************************构建大顶堆和小顶堆,并实现堆排序*********************************/
#include<stdio.h>
#include<math.h>
void heap_ajust_max(int *a, int i, int size)  /*a为堆存储数组,size为堆的大小*/
{
    int lchild = 2*i;       //i的左孩子节点序号 
    int rchild = 2*i +1;     //i的右孩子节点序号 
    int max = i; /*存放三个顶点中最大的数的下标*/
	int temp;
    if(i <= size/2)          //假设i是叶节点就不用进行调整 
    {
        if(lchild<=size && a[lchild]>a[max])
        {
            max = lchild;
        }    
        if(rchild<=size && a[rchild]>a[max])
        {
            max = rchild;
        }
        if(max != i)
        {
            temp = a[i]; /*交换a[i]和a[max]的值*/
			a[i] = a[max];
			a[max] = temp;
            heap_ajust_max(a, max, size); /*被交换的位置曾经是大根堆,如今可能不是大根堆
			                            所以须要又一次调整使其成为大根堆结构*/ 
        }
    }        
}

void heap_ajust_min(int *b, int i, int size)  /*a为堆存储数组,size为堆的大小*/
{
    int lchild = 2*i;       //i的左孩子节点序号 
    int rchild = 2*i +1;     //i的右孩子节点序号 
    int min = i; /*存放三个顶点中最大的数的下标*/
	int temp;
    if(i <= size/2)          //假设i是叶节点就不用进行调整 
    {
        if(lchild<=size && b[lchild]<b[min])
        {
            min = lchild;
        }    
        if(rchild<=size && b[rchild]<b[min])
        {
            min = rchild;
        }
        if(min != i)
        {
            temp = b[i]; /*交换a[i]和a[max]的值*/
			b[i] = b[min];
			b[min] = temp;
            heap_ajust_min(b, min, size); /*被交换的位置曾经是大根堆,如今可能不是大根堆
			                            所以须要又一次调整使其成为大根堆结构*/ 
        }
    }        
}

void build_bheap_max(int *a, int size) /*建立大根堆*/ 
{
    int i;
    for(i=size/2; i >= 1; i--) /*非叶节点最大序号值为size/2*/
    {
        heap_ajust_max(a, i, size); /*每一个非叶子结点都须要调用这个函数*/   
    }    
} 
void build_bheap_min(int *b, int size) /*建立小堆*/ 
{
    int i;
    for(i=size/2; i >= 1; i--) /*非叶节点最大序号值为size/2*/
    {
        heap_ajust_min(b, i, size); /*每一个非叶子结点都须要调用这个函数*/   
    }    
}
void heap_sort_max(int *a, int size)
{
    int i;
	int temp;
    for(i=size; i >= 1; i--)
    {
        temp = a[1];
		a[1] = a[i];
		a[i] = temp; //交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面
        heap_ajust_max(a, 1, i-1); //又一次调整堆顶节点成为大顶堆,仅仅有被交换的分支才有可能不是大根堆
    }
} 

void heap_sort_min(int *b, int size)
{
    int i;
	int temp;
    for(i=size; i >= 1; i--)
    {
        temp = b[1];
		b[1] = b[i];
		b[i] = temp; //交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面
        heap_ajust_min(b, 1, i-1); //又一次调整堆顶节点成为大顶堆,仅仅有被交换的分支才有可能不是大根堆
    }
} 

int main(int argc, char *argv[])
{
    int a[]={0,52,28,45,29,36,35,51,46,47,100,75,59,63,72,68,73,85,76,98,92};
    int size = sizeof(a)/sizeof(int) -1;
	int i;
	int j;
	int count=1;
	printf("size = %d\n", size);
    //heap_sort(a, size);
	build_bheap_max(a, size);
	printf("大顶堆:\n"); 
	for(i=0;i<=4;i++)
	{
		for(j=0;j<pow(2,i);j++)
		{
			if(count<=size)
			{
				printf("%d ",a[count++]);
			}else{
				break;
			}
		}
		printf("\n");
	}
    printf("\n");
	printf("堆排序之后的序列为:\n");
	heap_sort_max(a, size);
	for(i=1;i <= size; i++)
        printf("%d ", a[i]);
    printf("\n");
	int b[]={0,52,28,45,29,36,35,51,46,47,100,75,59,63,72,68,73,85,76,98,92};
	build_bheap_min(b, size);
	printf("小顶堆:\n"); 
    count=1;
	for(i=0;i<=4;i++)
	{
		for(j=0;j<pow(2,i);j++)
		{
			if(count<=size)
			{
				printf("%d ",b[count++]);
			}else{
				break;
			}
		}
		printf("\n");
	}
    printf("\n");
	heap_sort_min(b, size);
	printf("堆排序之后的序列为:\n");
	for(i=1;i <= size; i++)
        printf("%d ", b[i]);
    printf("\n");
    return 0;
}
如有疑问,请及时提出,谢谢!

--------------------------------------------------------------------------------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/zly412934578/article/details/79146985