堆以及堆排序简单实现(C++)

学习这一章节之后,自己试着实现了以下:

数据结构与算法之美:28 | 堆和堆排序:为什么说堆排序没有快速排序快?

很多地方处理的比较仓促:

#include <iostream>
#include <vector>

using namespace std;

//大顶堆(基于vector)
template<class T>
class Heap{
public:
	Heap(); //默认构造
	Heap(int cap); //构造大小为cap的堆
	Heap(vector<T> &vec, int len); //从数组vec构造一个堆

	int size() const;
	int maxSize() const;
	bool empty() const;
	void push(T value); //插入新元素
	void pop(); //删除堆顶元素
	const T& top() const; //获取堆顶元素(最大值或者优先级最高的值)
	void print();//打印
	//对堆内的数据进行排序,返回一个排序后的数组
	//不改变原有的堆
	vector<T> sort(); 

private:
	void heapify(vector<T> &vec, int count, int i); //自上而下堆化
	void swap(vector<T> &vec, int i, int j); //元素交换
	vector<T> data; //底层是数组
	int count = 0; //元素个数
	int capacity; //容量
};

template<class T>
Heap<T>::Heap(){
	capacity = 10; //默认容量10
	//count = 0;
	data.resize(capacity + 1); //分配至少能容纳capacity+1个元素的空间(元素下标从1开始)
}

template<class T> 
Heap<T>::Heap(int cap){
	capacity = cap;
	//count = 0;
	data.resize(capacity + 1); //分配至少能容纳capacity+1个元素的空间(元素下标从1开始)
}

/*这儿使用的是第一种思路建堆(就是简单地不停插入元素)
template<class T> 
Heap<T>::Heap(vector<T> &vec, int len){ 
	capacity = len;
	//count = 0;
	data.resize(capacity + 1); //分配至少能容纳capacity+1个元素的空间(元素下标从1开始)
	for (int i = 0; i < len; ++i)	push(vec[i]);
}
*/

//使用第二中方式建堆
//从一个数组直接建堆
template<class T>
Heap<T>::Heap(vector<T> &vec, int len){ 
	capacity = len;
	data.resize(capacity + 1); //分配至少能容纳capacity+1个元素的空间(元素下标从1开始)
	for (int i = 1; i <= capacity; ++i){ //先将元素拷贝到data(data下标从1开始)
		data[i] = vec[i - 1];
		++count;
	}
	for (int i =  count/2; i >= 1; --i)	heapify(data, count, i);//建堆,从第一个非叶子结点开始自下而上
}

template<class T> 
int Heap<T>::size() const {
	return count;
}

template<class T> 
int Heap<T>::maxSize() const {
	return capacity;
}

template<class T> 
bool Heap<T>::empty()const {
	return count == 0;
}

template<class T> 
void Heap<T>::push(T value){
	if (count >= capacity){
		cerr << "heap已满,push失败!" << endl;
		return; 
	} 
	++count;
	data[count] = value;
	int i = count;
	while (i / 2 > 0 && data[i] > data[i / 2]){//自下而上堆化
		swap(data, i, i / 2);
		i = i / 2;
	}
}

template<class T> 
void Heap<T>::pop(){
	if (count == 0){
		cerr << "heap为空,无法pop()!" << endl;
	}
	else{
		data[1] = data[count];
		--count;
		heapify(data, count, 1);
	}
}

template<class T> 
const T &Heap<T>::top()const{
	if (count == 0){
		cerr << "heap为空,无法访问top()!" << endl;
	}else
		return data[1];
}

template<class T>
void Heap<T>::print(){
	for (int i = 1; i <= count; ++i)
		cout << data[i] << " ";
	cout << endl;
}

template<class T>
vector<T> Heap<T>::sort(){
	auto vec = data;
	//vec.erase(vec.begin());
	int n = count;
	while (n > 1){
		swap(vec, n, 1);
		--n;
		heapify(vec, n, 1);
	}
	vec.erase(vec.begin());//  //因为之前元素是从下标1开始的
	return vec;
}

template<class T> 
void Heap<T>::heapify(vector<T> &vec, int count, int i){
	while (true){
		int maxPos = i;
		if (2*i <= count && vec[i] < vec[2*i])	maxPos = 2*i;
		if (2*i+1 <= count && vec[maxPos] < vec[2*i+1])	maxPos = 2*i+1;
		if (i == maxPos) break;
		swap(vec, i, maxPos);
		i = maxPos;
	}
}

template<class T> 
void Heap<T>::swap(vector<T> &vec, int i, int j){
	auto tmp = vec[i];
	vec[i] = vec[j];
	vec[j] = tmp;
}

另外堆排序还可以参考这儿:

LeetCode第 215 题:数组中的第K个最大元素(C++)_qq_32523711的博客-CSDN博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值