STL_priority_queue模拟实现

目录

概述

模拟实现 

模板定义

结构定义 

 构造函数

默认构造 

迭代器区间构造

adjust_down

adjust_up 

接口函数


概述

priority_queue称为优先级队列,它实际是一个堆结构,底层采用vector容器进行实现。

模拟实现 

模板定义

priority_queue的优先级有两种:大的优先级高或小的优先级高,因此我们定义priority_queue的时候需要传一个模板参数来决定它的优先级。 

template<class T,class Container=vector<T>,class Compare=Less<T>>

我们可以通过实现Less类,重载它的()来实现优先级确定,也就是大小堆的实现。

Less表示建立的是大堆,也就是大的优先级高。

而Greater表示建立的是小堆,也就是小的优先级高。 

    template<class T>
	struct Less
	{
		bool operator()(const T& x, const T& y)
		{
			return x < y;
		}
	};
	template<class T>
	struct Greater
	{
		bool operator()(const T& x, const T& y)
		{
			return x > y;
		}
	};

结构定义 

优先级队列默认采用vector容器进行实现,所以成员是一个容器对象。

        private:
		Container _con;

 构造函数

由于成员变量是一个自定义类型,所以我们可以不写默认构造。

默认构造 

priority_queue()
		{

		}

 

迭代器区间构造

进行迭代去区间构造后,要将它重新调整成堆。

        template<class InputIterator>
		priority_queue(InputIterator first, InputIterator last)
			:_con(first,last)//调用容器的迭代器区间构造
		{
			for (int i = (size() - 1 - 1) / 2; i >= 0; i--)
			{
				adjust_down(i);//建堆
			}
		}

所以我们下面要实现向上调整和向下调整。 

adjust_down

我们可以通过使用compare类的重载后的()来实现大小的比较,所以,我们创造一个compare对象。

        void adjust_down(size_t parent)
		{
			Compare _com;
			size_t child = parent * 2 + 1;
			while (child < _con.size())
			{
				if (child + 1 < _con.size() && _com(_con[child],_con[child+1]))
				{
					child++;
				}
				//if (_con[child] > _con[parent])
				if (_com(_con[parent], _con[child]))
				{
					swap(_con[child], _con[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}

adjust_up 

        void adjust_up(size_t child)
		{
			Compare _com;
			size_t parent = (child - 1) / 2;
			while(child>0)
			{
				//if (_con[child] > _con[parent])
				if (_com(_con[parent],_con[child]))
				{
					swap(_con[child], _con[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}

 

接口函数

 

top返回堆顶元素
size返回元素个数
empty判空
push入队
pop出队

 

        const T& top()const
		{
			return _con.front();
		}
		bool empty()const
		{
			return _con.empty();
		}
		size_t size()const
		{
			return _con.size();
		}
		void push(const T& val)
		{
			_con.push_back(val);
			adjust_up(_con.size() - 1);
		}
		void pop()
		{
            //删除不能直接删,直接删破坏堆结构
            //所以我们交换第一个和最后一个元素
            //删除最后一个,然后进行调整
			assert(!_con.empty());
			swap(_con.front(), _con.back());
			_con.pop_back();
			adjust_down(0);
		}

 

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嚞譶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值