堆排序,用以下无序序列加以验证:49,38,65,97,76,13,27,49

堆排序,用以下无序序列加以验证:
49,38,65,97,76,13,27,49 

/*
堆排序,用以下无序序列加以验证:
49,38,65,97,76,13,27,49 
*/

#include <stdio.h>
#define N 9
//堆算法,模拟 完全二叉树的一种算法(核心是如根节点下标i 左子树下标等于2 * i 右子树等于左子树+1即2 * i + 1) 
//构造成一个大顶堆,k为要调整的非叶子结点下标,size为数组a[]的大小 
void adjust_mheap(int a[],int k,int size)
{
	int x = a[k];//要处理的元素 (这个始终不变)
	int j = 2 * k;//默认为 k 的左孩子下标 
	
	//开始从k 开始 下坠调整 
	while(j <= size)//如果k有左孩子(2 * k <= size数组大小)
	{
		if(j < size && a[j] < a[j + 1])//j < size说明k有右孩子,然后选择k的两个孩子中值大的进行比较(如果值比其还大 说明比孩子都大)
		{
			j ++;//说明右孩子大,把j + 1等于右孩子的下标 
		}
		//开始根节点值与 其最大的孩子结点 比较 
		if(x < a[j])//根是否比其小,满足则交换,大根堆保证 越小越往下走,局部最大值向上浮 
		{
			a[k] = a[j];//变化根的值为其该孩子的值,由于x始终保存起先a[k]的值,所以最先的根值不会遗失--*****
			k = j;      //然后记录 该孩子的地址 方便后面交换值 
			j = j * 2;  //再类似的 处理 这个孩子的孩子 
		}
		else
		{
			break; 
		}
	} 
	a[k] = x;//找到最开始的值 下沉的位置,然后赋值为最初传入的x值,形式上是x值与*号哪一行的a[k]值交换 
	return;
} 

//堆排序(不稳定算法)
void heapSort(int a[],int size)
{
	//建立初始大根堆 
	for(int i = size/2;i >= 1;i --)//(size - 1)/2为最后一个非叶结点,依次-1为倒数第二.... 
	{
		adjust_mheap(a,i,size);//参数:数组,开始调整的下标,数组长度。从最后一个非叶结点开始调整 
	}
	
	int x = 0;//作为交换媒介,用与最大值和最后每处理元素交换 
	for(int i = size;i >= 2;i --)
	{
		//大根堆的根为最大值(数组第一个元素),将其与当前没有处理的 最后一个元素交换 
		x = a[1];a[1] = a[i];a[i] = x;//exchange 
		//交换后排除最后一个元素(已经是有序),然后调整为大根堆
		adjust_mheap(a,1,i - 1);//由于此时只有1由于交换仍可能无序,故只用按照下标0进行 大根堆调整 
	} 
	
	return;   
}


void prin_a(int a[]);
int main()
{
	int a[N] = {0,49,38,65,97,76,13,27,49};//舍掉第一个 元素空间 不用 

	//快速排序 
	heapSort(a,N - 1);//参数:数组,实际处理元素个数(不包括舍弃的第一个空间) 
	//打印数组 
	prin_a(a);
	
	return 0;
}
//打印数组 
void prin_a(int a[])
{
	for(int i = 1;i < N;i ++)
	{
		printf("%d ",a[i]);
	}
	printf("\n");
	return;
}

猜你喜欢

转载自blog.csdn.net/qq_47991812/article/details/121460758
49
今日推荐