CPP(七):priority_queue的实现与大根堆的使用

实现的一个按int类型值从大到小的优先队列,使用大根堆实现。


#include 
#include 
using namespace std;

class priority_queue
{
private:
	vector data;// data[0] is not used
	void sift_up(int index)
	{
		int parent_index = index / 2;
		if (parent_index == 0)
		{
			return;
		}
		else
		{
			if (data[index] > data[parent_index])
			{
				int temp = data[index];
				data[index] = data[parent_index];
				data[parent_index] = temp;
				sift_up(parent_index);
			}
		}
	}
	void sift_down(int index)
	{
		int left_son_index = index * 2;
		if (left_son_index >= (int)data.size())
		{
			return;
		}
		else
		{
			// which son to swap with
			int swap_index = left_son_index;
			if (left_son_index + 1 < (int)data.size() && data[left_son_index] < data[left_son_index] + 1)
			{
				swap_index = left_son_index + 1;
			}
			// swap!
			if (data[index] < data[swap_index])
			{
				int temp = data[index];
				data[index] = data[swap_index];
				data[swap_index] = temp;
				sift_down(swap_index);
			}
		}
	}
	void insert(int value)
	{
		data.push_back(value);
		sift_up(data.size() - 1);
	}
public:
	priority_queue()
	{
		data.push_back(0);// data[0] is not used
	}
	void push(int value)
	{
		insert(value);
	}
	void pop()
	{
		if (data.size() > 1)
		{
			data[1] = data[data.size() - 1];
			data.erase(data.end() - 1);
			sift_down(1);
		}
	}
	int top()
	{
		if (data.size() > 1)
		{
			return data[1];
		}
		else
		{
			// raise error!
			return 0;
		}
	}
};

void test_priority_queue()
{
	priority_queue pqueue;
	pqueue.push(2);
	pqueue.push(3);
	pqueue.push(1);
	for (int i = 0; i < 3; ++i)
	{
		cout << pqueue.top() << endl;
		pqueue.pop();
	}
}

int main()
{
	test_priority_queue();
	return 0;
}


在上面的程序的基础上,我们再添加C++的一些语法机制,可以实现一个功能上和STL中priority_queue一模一样的类。

下面是代码:

#include 
#include 
using namespace std;
// 下面实现了一个优先级队列。
// 它的用法和STL中的priority_queue是一样的。
template 
class priority_queue
{
private:
	STORAGE_CONTAINER data;// data[0] is not used
	void sift_up(int index)
	{
		COMPARE_CLASS comp;
		int parent_index = index / 2;
		if (parent_index == 0)
		{
			return;
		}
		else
		{
			if (comp(data[index], data[parent_index]))
			{
				ELEMENT_TYPE temp = data[index];
				data[index] = data[parent_index];
				data[parent_index] = temp;
				sift_up(parent_index);
			}
		}
	}
	void sift_down(int index)
	{
		COMPARE_CLASS comp;
		int left_son_index = index * 2;
		if (left_son_index >= (int)data.size())
		{
			return;
		}
		else
		{
			// which son to swap with
			int swap_index = left_son_index;
			if (left_son_index + 1 < (int)data.size() && !comp(data[left_son_index], data[left_son_index + 1]))
			{
				swap_index = left_son_index + 1;
			}
			// swap!
			if (!comp(data[index], data[swap_index]))
			{
				ELEMENT_TYPE temp = data[index];
				data[index] = data[swap_index];
				data[swap_index] = temp;
				sift_down(swap_index);
			}
		}
	}
	void insert(ELEMENT_TYPE &value)
	{
		data.push_back(value);
		sift_up(data.size() - 1);
	}
public:
	priority_queue()
	{
		data.push_back(0);// data[0] is not used
	}
	void push(ELEMENT_TYPE &value)
	{
		insert(value);
	}
	void pop()
	{
		if (data.size() > 1)
		{
			data[1] = data[data.size() - 1];
			data.erase(data.end() - 1);
			sift_down(1);
		}
	}
	ELEMENT_TYPE top()
	{
		if (data.size() > 1)
		{
			return data[1];
		}
		else
		{
			// raise error!
			return 0;
		}
	}
	bool empty()
	{
		return data.size() == 1;
	}
	size_t size()
	{
		return data.size() - 1;
	}
};
// 实现一个“人物类”,将此类作为元素添加到优先级队列中做测试。
// 人的年龄与优先级成正比。
struct person
{
	int age;
	person()
	{
		age = 0;
	}
	person(int init_age)
	{
		age = init_age;
	}
};
struct compare_person
{
	bool operator()(const person& left, const person& right) const
	{
		return left.age > right.age;
	}
};
ostream &operator<<(ostream &os, person &p)
{
	cout << "I'm " << p.age << " years old.";
	return os;
}
// 测试函数:测试实现的优先级队列是否可以正常工作。
void test_priority_queue()
{
	priority_queue, compare_person> pqueue;
	pqueue.push(person(11));
	pqueue.push(person(13));
	pqueue.push(person(12));
	cout << pqueue.size() << endl;
	while (!pqueue.empty())
	{
		cout << pqueue.top() << endl;
		pqueue.pop();
	}
}
int main()
{
	test_priority_queue();
	return 0;
}


你可能感兴趣的:(C++)