堆排序详解

本文介绍了堆排序的基础知识,包括堆的定义和完全二叉树的性质。堆排序通过构建大顶堆或小顶堆,确保每个父节点大于或小于其子节点,从而在数组中找到最大或最小元素。在实现过程中,通过交换根节点和数组末尾元素并重新调整堆,实现排序。文章还指出,在交换后可能需要对左孩子和右孩子进行额外的堆调整以保持堆的正确性。
摘要由CSDN通过智能技术生成

在学习堆排序前要先知道什么是堆

百度百科上给出的定义:堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵完全二叉树的数组对象。

实际上就是将完全二叉树按行线性化存入数组中,所以呈现出的规律就是,每一个父节点下标x[i]对应的左孩子下标为x[i*2+1],右孩子下标为x[i*2+2]

基于数组实现堆的基础上对堆进行大顶堆变换或者小顶堆变换,即让每个父节点都大于两个孩子结点(大顶堆)或者小于两个孩子结点(小顶堆),根据树的特性【根为最开始的父节点】所以根结点就会变成最大的或者最小的,因此得到以下操作

1.对数组1~n进行大顶堆或者小顶堆变换,让所有结点都满足a[i]>a[i*2+1]&&a[i]>a[i*2+2]

这里i*2+1是左孩子下标,i*2+2是右孩子下标(堆定义的下标规律)

2.将根节点a[1]和数组末尾a[n]交换,继续对1~n-1进行堆变换,使其满足上述条件

int a[10]={1,9,8,7,6,5,4,3,2,10};

void createMaxHeap(int n){
	for(int i=n;i>=0;i--){
		int lChild=2*i+1,rChild=lChild+1;
		if(lChild<=n&&a[lChild]>a[i]){
			swap(a[lChild],a[i]);
			int llChild=lChild*2+1,rrChild=llChild+1;
			if(llChild<n&&a[llChild]>a[lChild])createMaxHeap(n);
			if(rrChild<n&&a[rrChild]>a[lChild])createMaxHeap(n);
		}
		if(rChild<=n&&a[rChild]>a[i]){
			swap(a[rChild],a[i]);
			int llChild=rChild*2+1,rrChild=llChild+1;
			if(llChild<n&&a[llChild]>a[rChild])createMaxHeap(n);
			if(rrChild<n&&a[rrChild]>a[rChild])createMaxHeap(n);
		}
	}
}

void heapSort(){
	for(int i=9;i>=0;i--){
	    createMaxHeap(i);
	    swap(a[i],a[0]);	
	}
}

这里存在的一个问题是,左孩子和父结点交换后可能使交换后的左孩子  堆结构混乱(也就是不满足父节点大于两个孩子结点)所以交换后要对左孩子和右孩子的堆结构进行判断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值