数据结构用C++实现堆排序

堆排序

对于一个数组,总能用完全二叉树的方式去理解他,例如对于数组,

536604248
可以表示为完全二叉树如下
5
3
6
6
0
4
2
4
8

1. 初始化堆
堆就是,root节点总是比他的两个子节点的值要大,从最后一个非叶子节点(len/2-1)开始进行堆调整,本例是从第二个6开始,其下标正好也必然是len/2-1,若发现其子节点有大于当前节点的,则将最大的子节点与当前节点进行交换,进行一步交换形成二叉树:

5
3
6
8
0
4
2
4
6

当然实际上是数组中数的值在改变。需要注意的是,在调整的过程中,如 上一个图,若3与8交换,则3的位置仍然需要进行堆调整,3再与6交换;经过一轮调整后,形成二叉树如下,

8
6
6
5
0
4
2
4
3

2. 交换堆顶和最后一个元素
由于是从小到大排序,所以最大元素放置最后,形成:

3
6
6
5
0
4
2
4
8

3. 再次进行堆调整
此时最后一个元素以符合要求,然后从二叉树的第一个元素,再开始进行堆调整,注意此时不要把最后已排好的元素算进来,否则8会重新升至顶.

代码
#include<iostream>
#include<vector>
#include<time.h>
using namespace std;
/*
 	pos 待调整的数组的节点位置 
 	len 需要调整的最大下标,不是数组的实际长度,大于len下标表示是已经调整好的,无需再进行
*/
void heapadjust(vector<int> &nums, int pos,int len){
	int index = pos;
	int lchild = pos*2 + 1;
	int rchild = pos*2 + 2;
	if (lchild<len && nums[lchild]>nums[index])
	 	 index = lchild;
	if (rchild<len && nums[rchild]>nums[index])
	  	 index = rchild;
	if (index != pos){
		 swap(nums[index], nums[pos]);
		 heapadjust(nums, index,len);//若进行调整,则必须递归调整下面部分
	}
}
void heapsort(vector<int> &nums){
	 int len = nums.size();
	 //1、初始化堆
	 for (int i = len/2 - 1; i >= 0; --i){//从最后一个非叶子节点开始调整堆
	  	heapadjust(nums,i,len);//调整子节点值都小于root节点值
	 }
	 /* 此时最大元素已至堆顶 */
	 /* 2、交换堆顶(0)和最后元素(i)*/
	 for (int i = len-1; i >= 0; --i){
		  swap(nums[0], nums[i]);
		  heapadjust(nums, 0, i);//这里必须限制i,若不在i前截至,则已经放置最后的最大的元素会被重新放置堆顶
	 }
}

int main(){
	 srand((unsigned int)time(NULL));
	 //定义数组
	 vector<int> arr;
	 for (int i = 0; i < 10; ++i){
		  int num = rand() % 100;
		  arr.push_back(num);
	 }
	 heapsort(arr);
	 for (auto i : arr)
	  	cout << i << ' ';
	 cout << endl;
	 system("pause");
	 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值