您的位置:首页 > 理论基础 > 数据结构算法

数据结构--优先级队列

2016-04-27 11:24 337 查看
优先级队列:优先级队列 是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。(优先权可根据具体形势具体定义)

优先级对列是堆的应用之一, 它的具体实现以堆为原型。

仿函数:

<span style="font-size:18px;">//仿函数比较小
template<class T>
struct Less
{
bool operator() (const T& l, const T& r)
{
return l < r;
}
};
//仿函数比较大
template<class T>
struct Greater
{
bool operator() (const T& l, const T& r)
{
return l > r;
}
};</span>


堆:

<span style="font-size:18px;">//template<class T, class Compare = Less<T>>
//适配器模式  默认为Less比较模式
template<class T, template<class> class Compare = Less>
class Heap
{
public:
//无参构造函数
Heap()
{}
//带参
Heap(const T* a, size_t size)
{
_a.reserve(size);  //先开辟空间
for (size_t i = 0; i < size; ++i)
{
_a.push_back(a[i]);  //push 数据
}

// 建堆
for (int i = (_a.size() - 2) / 2; i >= 0; --i)
{
_AdjustDown(i);  //从第一个非叶子节点下调
}
}
//
Heap(vector<T>& a)
{
_a.swap(a);  //交换两个vector

// 建堆
for (int i = (_a.size() - 2) / 2; i >= 0; --i)
{
_AdjustDown(i);
}
}

//插入数据
void Push(const T& x)
{
_a.push_back(x); //尾插

_AdjustUp(_a.size() - 1); //上调  从下向上进行调整
}
//pop数据
void Pop()
{

size_t size = _a.size();
assert(size > 0); //防御式编程

swap(_a[0], _a[size - 1]);  //交换两个数据
_a.pop_back();  //尾删
_AdjustDown(0);  //上调
}
//取堆顶元素
T& Top()
{
assert(!_a.empty());
return _a[0];
}

size_t Size()
{
assert(_a.size() > 0);
return _a.size();
}
bool Empty()
{
return _a.size() == 0;
}

void Print()
{
for (int i = 0; i < _a.size(); i++)
{
cout << _a[i] << "  ";
}
cout << endl;
}

protected:
//上调
void _AdjustUp(int child)
{
int parent = (child - 1) / 2;
//while(parent>=0)
while (child > 0)
{
Compare<T> com;  //会调用相应的仿函数进行比较,
//Compare com;
//if (_a[child] > _a[parent])
if (com(_a[child], _a[parent]))  //如果满足各自的条件,就进行交换,然后在继续
{
swap(_a[child], _a[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}

void _AdjustDown(size_t parent)
{
size_t child = parent * 2 + 1;
while (child < _a.size())
{
// 选出孩子里面大的那一个
//Compare com;
Compare<T> com;
//if (child+1 < _a.size() &&_a[child+1] > _a[child])
if (child + 1 < _a.size()
&& com(_a[child + 1], _a[child]))
{
++child;
}

// 如果父亲小于孩子,则交换并继续往下调整
// 否则调堆完成

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

protected:

vector<T> _a;
};</span>


优先级对列:

<span style="font-size:18px;">//优先级队列  默认以小的优先级高
template <class T, template<class> class Compare = Less>
class PriorityQueue
{
public:
void Push(const T& x)
{
_hp.Push(x);
}

void Pop()
{
_hp.Pop();
}

T& Top()
{
return _hp.Top();
}

size_t Size()
{
return _hp.Size() ;
}
bool Empty()
{
return _hp.Size() == 0;
}

void Print()
{
_hp.Print();
}

protected:
Heap<T, Compare> _hp;
};
</span>


测试用例1:

<span style="font-size:18px;">void Test1()
{
int a[] = { 10, 11, 13, 12, 16, 18, 15, 17, 14, 19 };
PriorityQueue<int, Greater> p;
p.Push(10);
p.Push(11);
p.Push(13);
p.Push(12);
p.Push(16);
p.Push(18);
p.Push(15);
p.Push(17);
p.Push(14);
p.Push(19);
p.Print();
cout << p.Empty() << endl;
cout << p.Size() << endl;
cout << p.Top() << endl;
}
</span>



测试用例2:

<span style="font-size:18px;">void Test2()
{
int a[] = { 10, 11, 13, 12, 16, 18, 15, 17, 14, 19 };
PriorityQueue<int, Greater> p;
p.Push(10);
p.Push(11);
p.Push(13);
p.Push(12);
p.Push(16);
p.Push(18);
p.Push(15);
p.Push(17);
p.Push(14);
p.Push(19);

p.Print();
p.Pop();
p.Print();
p.Pop();
p.Print();
p.Pop();
p.Print();
p.Pop();
p.Print();
p.Pop();
p.Print();
p.Pop();
p.Print();
p.Pop();
p.Print();
p.Pop();
p.Print();
p.Pop();
p.Print();
p.Pop();
p.Print();

}</span>




仿函数测试用例:

<span style="font-size:18px;">void TestFuner()
{
Less<int> less;
cout << less(1, 2) << endl;
cout << less(3, 2) << endl;
cout << less(4, 2) << endl;
cout << less(-1, 2) << endl;
cout << "-------" << endl;;
Greater<int> greater;
cout << greater(1, 2) << endl;
cout << greater(3, 2) << endl;
cout << greater(4, 2) << endl;
cout << greater(-1, 2) << endl;
}
</span>


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: