模拟实现priority_queue优先级队列

优先级队列

无参构造
priority_queue()
			:c()
		{}
区间构造

区间构造需要用到迭代器,而迭代器每个容器的类型不一样,所以用模板给出,初始化列表,把用户给进来的元素空间起始位置,放到优先级队列中底层空间的位置,然后进行调整,把它调整成一个堆

template<class Iterator>
		priority_queue(Iterator first, Iterator last)
			: c(first,last)
		{
			//将c中的元素调整成堆的结构
			size_t count = c.size();
			//倒数第一个非叶子结点
			int root = (count - 2) / 2;
			for (; root >= 0; root--)
				AdjustDown(root);
		}
元素操作
void push(const T& data)
		{
			c.push_back(data);
			//插完元素后,破坏了堆的性质,重新调整
			AdjustUp(c.size() - 1);
		}

		void pop()
		{
			if (empty())
				return;
			swap(c.front(), c.back());
			c.pop_back();
			//重新调整
			AdjustDown(0);
		}

		size_t size()const
		{
			return c.size();
		}

		bool empty()const
		{
			return c.empty();
		}

		//堆顶元素不允许修改,因为堆顶元素修改可能会破坏堆的特性
		const T& top() const
		{
			return c.front();
		}
向下调整和向上调整

参考下面这个链接里的内容
详解堆的应用

如何判断com中双亲放在前面还是孩子放在前面

默认按照less方式进行比较
less---->大堆------->大的元素往上提

com(c[parent],c[child])

双亲比孩子小,让孩子往上走

bool operator()(const T& left ,const T& right)
{
	return left < right;
}

大于的方式比较-------小堆
小于的方式比较-------大堆

完整代码

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

namespace bite
{
	template<class T ,class Container = vector<T>,class Compare = less<T>>
	class priority_queue
	{
	public:
		priority_queue()
			:c()
		{}

		template<class Iterator>
		priority_queue(Iterator first, Iterator last)
			: c(first,last)
		{
			//将c中的元素调整成堆的结构
			size_t count = c.size();
			//倒数第一个非叶子结点
			int root = (count - 2) / 2;
			for (; root >= 0; root--)
				AdjustDown(root);
		}

		void push(const T& data)
		{
			c.push_back(data);
			AdjustUp(c.size() - 1);
		}

		void pop()
		{
			if (empty())
				return;
			swap(c.front(), c.back());
			c.pop_back();
			AdjustDown(0);
		}

		size_t size()const
		{
			return c.size();
		}

		bool empty()const
		{
			return c.empty();
		}

		//堆顶元素不允许修改,因为堆顶元素修改可能会破坏堆的特性
		const T& top() const
		{
			return c.front();
		}
	private:
		void AdjustDown(int parent)
		{
			int child = parent * 2 + 1;
			while (child < c.size())
			{
				//找以parent为根的两个孩子中较大的孩子
				if (child + 1 < c.size() && com(c[child], c[child + 1]))
					child += 1;
				
				//检测双亲是否满足情况
				if (com(c[parent] , c[child]))
				{
					swap(c[child], c[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
					return;
			}
		}

		void AdjustUp(int child)
		{
			int parent = (child - 1) / 2;

			while (child)
			{
				if (com(c[parent] , c[child]))
				{
					swap(c[child], c[parent]);
					child = parent;
					parent = (child - 1) / 2;

				}
				else
				{
					return;
				}
			}
		}
	private:
		Container c;	//存储方式
		Compare com;  //比较方式
	};

}

测试

int main()
{
	int array[] = { 8, 1, 9, 3, 6, 4, 5, 0, 2, 7 };
	bite::priority_queue<int>q(array, array + sizeof(array) / sizeof(array[0]));
	cout << q.top() << endl;
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值