heap构建

自定义堆数据结构实现
#pragma once
#include <vector>
#include <iostream>
using namespace std;

enum heapType
{
	MAXHEAP, MINHEAP
};
template<typename T>
class MyHeap
{
private:
	std::vector<T> _vecdate;
	int _size;//元素数量
	int _capacity;//整个堆的大小
	heapType _type;
public:
	MyHeap(T data[], int len, heapType type);
	MyHeap(int capacity, heapType type);//空堆
	//virtual ~MyHeap();
	bool push(T date);
	bool pop(int index);
	void print();
	bool full()
	{
		if (_size >= _capacity)
		{
			return true;
		}
		return false;
	}
	bool empty()
	{
		return _size == 0;
	}
	void _swap(int index1, int index2);
private:
	
	void _sink(int index);//元素下沉(删除元素)
	void _floating(int index);//元素上浮(添加元素)
};

template <typename T>
MyHeap<T>::MyHeap(T date[], int len, heapType type) :_size(0), _capacity(len), _type(type)
{
	_vecdate.resize(_capacity);
	for (int i = 0; i < len; i++)
		push(date[i]);
}

template<typename T>
MyHeap<T>::MyHeap(int capacity, heapType type) :_size(0), _capacity(capacity), _type(type)
{
	_vecdate.resize(_capacity);
}

template<typename T>
bool MyHeap<T>::push(T date)
{
	if (full())
	{
		throw("The heap is full!\n");
		return false;
	}
	else
	{
		_vecdate[_size] = date;
		_size++;
		_floating(_size);//调整堆的结构,使得新添加的数据符合堆的形式
		return true;
	}
}

template<typename T>
bool MyHeap<T>::pop(int index)
{
	if (empty())
	{
		throw("The heap is an empty heap!\n");
		return false;
	}
	else
	{
		_vecdate[index] = _vecdate[_size - 1];
		_size--;
		_sink(index + 1);
		return true;
	}
}

template<typename T>
void MyHeap<T>::print()
{
	for (int i = 0; i < _size; i++)
		std::cout << _vecdate[i] << "	";
	std::cout << std::endl;
	return;
}

template<typename T>
void MyHeap<T>::_swap(int index1, int index2)
{
	T tmp = _vecdate[index1];
	_vecdate[index1] = _vecdate[index2];
	_vecdate[index2] = tmp;
	return;
}

template<typename T>
void MyHeap<T>::_floating(int index)
{
	if (_size == 1)
		return;
	if (_type == MINHEAP)
	{
		for (; index > 0; index /= 2)
		{
			if (_vecdate[index - 1] < _vecdate[index * 0.5 - 1])
				_swap(index - 1, index * 0.5 - 1);
			else
				break;
		}
	}
	else if (_type == MAXHEAP)
	{
		for (; index > 0; index /= 2)
		{
			if (_vecdate[index - 1] > _vecdate[index * 0.5 - 1])
				_swap(index - 1, index * 0.5 - 1);
			else
				break;
		}
	}
	return;
}

template<typename T>
void MyHeap<T>::_sink(int index)
{
	if (_type == MINHEAP)
	{
		while (index * 2 <= _size)
		{
			//左节点
			if (_vecdate[index - 1] > _vecdate[index * 2 - 1])
			{
				_swap(index - 1, index * 2 - 1);
				//继续与右节点比较
				if (index * 2 + 1 <= _size && _vecdate[index - 1] > _vecdate[index * 2])
				{
					_swap(index - 1, index * 2);
				}
				index = index * 2;
			}
			//右节点
			else if (index * 2 + 1 <= _size && _vecdate[index - 1] > _vecdate[index * 2])
			{
				_swap(index - 1, index * 2);
				index = index * 2;
			}
			else
				break;
		}
	}
	else if (_type == MAXHEAP)
	{
		while (index * 2 <= _size)
		{
			//左节点
			if (_vecdate[index - 1] < _vecdate[index * 2 - 1])
			{
				_swap(index - 1, index * 2 - 1);
				//继续与右节点比较
				if (index * 2 + 1 <= _size && _vecdate[index - 1] < _vecdate[index * 2])
				{
					_swap(index - 1, index * 2);
				}
				index = index * 2;
			}
			//右节点
			else if (index * 2 + 1 <= _size && _vecdate[index - 1] < _vecdate[index * 2])
			{
				_swap(index - 1, index * 2);
				index = index * 2;
			}
			else
				break;
		}
	}
	else
		return;
}

 

`push_heap` 是 C++ 标准库中用于维护 **Heap)** 结构的算法之一,定义在 `<algorithm>` 头文件中。它用于将一个刚插入到容器末尾的元素“上浮”到合适的位置,以保持整个区间满足序性质(最大或最小)。 通常配合 `std::vector` 和 `std::make_heap`、`std::pop_heap` 等函数使用,是实现自定义操作的核心工具。 --- ### ✅ 基本语法 ```cpp void push_heap(RandomIt first, RandomIt last); void push_heap(RandomIt first, RandomIt last, Compare comp); ``` - `[first, last)`:必须是一个有效的,且新元素已经插入到 `last - 1` 的位置。 - `comp`:可选比较函数对象(如 `greater<int>()` 表示最小)。 - 调用后,整个区间重新调整为合法的。 > ⚠️ 注意:`push_heap` 并不负责插入元素,你需要先用 `container.push_back()` 插入元素,然后再调用 `push_heap` 来调整结构。 --- ### 🔧 使用步骤 1. 将新元素添加到容器末尾(例如 `vec.push_back(x);`) 2. 调用 `push_heap(vec.begin(), vec.end());` 来恢复序 --- ### 📌 示例:手动实现最大 ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { vector<int> heap; // 初始插入几个元素并构建 heap.push_back(10); push_heap(heap.begin(), heap.end()); // [10] heap.push_back(30); push_heap(heap.begin(), heap.end()); // 上浮 30 → [30,10] heap.push_back(20); push_heap(heap.begin(), heap.end()); // 上浮 20 → [30,10,20] heap.push_back(5); push_heap(heap.begin(), heap.end()); // → [30,10,20,5] cout << "Top of heap: " << heap.front() << endl; // 输出 30 // 打印当前结构(注意:不是排序结果) cout << "Heap: "; for (int x : heap) cout << x << " "; cout << endl; return 0; } ``` 输出: ``` Top of heap: 30 Heap: 30 10 20 5 ``` --- ### 🔄 对比 `std::priority_queue` | 特性 | `std::priority_queue` | 手动使用 `push_heap` | |------|------------------------|------------------------| | 底层 | 封装了 `vector` + 算法 | 需要手动管理 | | 易用性 | 高(直接 `push/pop`) | 中(需配合 `push_back`) | | 灵活性 | 低(不能遍历或修改内部) | 高(可访问所有元素) | | 是否支持遍历 | 否 | 是 | --- ### 🛠 示例:实现最小(使用 `greater<int>`) ```cpp #include <iostream> #include <vector> #include <algorithm> #include <functional> // greater using namespace std; int main() { vector<int> minHeap; auto push = [&](int val) { minHeap.push_back(val); push_heap(minHeap.begin(), minHeap.end(), greater<int>()); }; push(30); push(10); push(20); push(5); cout << "Min element: " << minHeap.front() << endl; // 输出 5 cout << "Min-Heap: "; for (int x : minHeap) cout << x << " "; cout << endl; return 0; } ``` 输出: ``` Min element: 5 Min-Heap: 5 10 20 30 ``` --- ### ❗ 常见错误 #### 错误写法(忘记先 push_back): ```cpp vector<int> heap; push_heap(heap.begin(), heap.end(), 42); // ❌ 错!没有元素怎么上浮? ``` #### 正确顺序: ```cpp heap.push_back(42); // 先插入 push_heap(heap.begin(), heap.end()); // 再调整 ``` --- ### 💡 实际应用场景 - 自定义动态结构(比如需要修改某个中间节点) - 实现 Dijkstra 或 Prim 算法时对优先队列进行优化更新 - 数据流中频繁插入/删除极值 - 替代 `priority_queue` 获取更多控制权 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值