【C++】优先级队列priority_queue模拟实现

文章目录

  • 一、介绍
    • 1. 使用
  • 二、模拟实现
    • 1. 构造函数
    • 2. 进队出队
    • 3. 向上调整向下调整
    • 4. 适配器的迭代器区间构造
    • 5. 仿函数

一、介绍

【C++】优先级队列priority_queue模拟实现_第1张图片

默认适配器是vector

整个数据结构是一个堆

image-20220406164434905


1. 使用

默认大的优先级高,是一个大堆

image-20220406171117026

#define _CRT_SECURE_NO_WARNINGS

#include 
#include 
#include 
using namespace std;

int main()
{
	priority_queue<int> pq;
	pq.push(1);
	pq.push(5);
	pq.push(3);
	pq.push(4);
	pq.push(2);

	while (!pq.empty())
	{
		cout << pq.top() << endl;
		pq.pop();
	}

	cout << endl;

	return 0;
}

测试结果:

【C++】优先级队列priority_queue模拟实现_第2张图片


仿函数是grearter是小堆

priority_queue<int, vector<int>, greater<int>> pq;

【C++】优先级队列priority_queue模拟实现_第3张图片


二、模拟实现

结构

#pragma once
#include 
#include 
#include 
using namespace std;

namespace wyj
{
	template<class T, class Container = vector<T>>
	class priority_queue
	{
    public:
        //成员函数
	private:
		Container _con;
};

1. 构造函数

因为用的是自定义类型(vector),调用自己的构造函数

priority_queue()
{}

2. 进队出队

	    void push(const T& x)
		{
			_con.push_back(x);
			adjust_up(_con.size() - 1);
		}

		void pop()
		{
			//防止结构乱掉先交换第一个和最后一个
			//需要进行向上调整
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			adjust_down(0);
			
		}

		bool empty()
		{
			return _con.empty();
		}

		size_t size()
		{
			return _con.size();
		}

		T& top()
		{
			return _con[0];
		}

3. 向上调整向下调整

		//先模拟实现大堆类型的
	private:
		void adjust_up(size_t child)
		{
			int parent = (child - 1) / 2;

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

		void adjust_down(size_t parent)
		{
			//大堆
			//有左孩子不一定右孩子
			int child = 2 * parent + 1;


			while (child < _con.size())
			{
				//先挑出孩子里大的那个
				if (child + 1 < _con.size() && _con[child + 1] > _con[child])
				{
					child++;
				}

				if (_con[child] > _con[parent])
				{
					swap(_con[child], _con[parent]);
					parent = child;
					child = 2 * parent + 1;
				}
				else
				{
					break;
				}

			}
		}

4. 适配器的迭代器区间构造

		//迭代器区间构造(适配器的迭代器)
		template <class InputIterator>
		priority_queue(InputIterator first, InputIterator last)
			:_con(first, last)
		{
			//迭代器区间构造完之后,不是一个堆,现在需要建堆
			//向下调整必须子节点都是堆
			//向上调整需要判断左右孩子存在
			for (int i = (_con.size() - 2) / 2; i >= 0; i--)
			{
				adjust_down(i);
			}
		}

  • 对以上进行测试
	void test1()
	{
		priority_queue<int, vector<int>> pq;
		pq.push(1);
		pq.push(5);
		pq.push(3);
		pq.push(4);
		pq.push(2);

		while (!pq.empty())
		{
			cout << pq.top() << endl;
			pq.pop();
		}

		cout << endl;

	}

【C++】优先级队列priority_queue模拟实现_第4张图片


5. 仿函数

实际上是一个类

image-20220407124857731

上面模拟实现缺少这个东西


  • 仿函数例子

一个类里面有个operator()

使用方法和函数调用一样

struct Less
{
    //这里不能直接写int& x,涉及引用不能是左值问题以后会单独谈
	bool operator()(const int& x, const int& y)
	{
		return x < y;
	}
};

struct Greater
{
	bool operator()(const int& x, const int& y)
	{
		return x > y;
	}
};

int main()
{
	Less less;
	cout << less(1, 2) << endl;
	Greater gt;
	cout << gt(4, 2) << endl;
	return 0;
}

这只是int,弄成模板的模样

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

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

这里就需要修改之前的向上调整和向下调整了

【C++】优先级队列priority_queue模拟实现_第5张图片


测试:

【C++】优先级队列priority_queue模拟实现_第6张图片


你可能感兴趣的:(C++,programing,langua,queue,stl,priority_queue,优先级队列)