一、优先级队列:
优先级队列(priority queue)是一种容器适配器,
它默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。
注意:默认情况下priority_queue是大堆。
向上和向下调整
首先:既然是堆就肯定有向上和向下调整,这些在之前学习中就已经学过了:
void AdjustDown(int parent)
{
int child = parent * 2 + 1;
while (child < _con.size())
{
//先找到子节点的小些的那个
if (child + 1 < _con.size() && _con[child] < _con[child + 1])
{
child++;
}
if (_con[parent] < _con[child])
{
swap(_con[child], _con[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void AdjustUp(int child)
{
int parent = (child - 1) / 2;
while (child > 0)
{
if (_con[parent] < _con[child])
{
swap(_con[child], _con[parent]);
child = parent;
parent = (child - 1) / 2;
}
else {
break;
}
}
}
默认构造函数:
首先,在模拟实现中,只有一个成员变量_con,它的类型默认就是vector,一般不会改变的,那么在实现构造函数中,就可以让这个自变量自己去调用它的构造函数。
push:
思路:
将传过来的那个值直接通过容器vector尾插进入,然后在进行向上调整即可。
void push(const T& x)
{
_con.push_back(x);
AdjustUp(_con.size() - 1);
}
头删pop:
思路:
首先要知道,是不能够直接删除最开始的位置的,如果删了,那么就会将堆的顺序搞混乱,所以要先将根位置和末位置交换,在进行尾删即可。
void pop()
{
swap(_con[0], _con[_con.size() - 1]);
_con.pop_back();
AdjustDown(0);
}
访问堆顶元素top:
思路:
容器毕竟是vector,那么直接用[] 访问第一个元素即可
const T& top()
{
return _con[0];
}
判断堆顶元素是否为空:
思路同上
bool empty()
{
return _con.empty();
}
计算堆的个数有多少:
size_t size()
{
return _con.size();
}
二、仿函数:
1、定义:
仿函数实际上就是让一个类在使用上像一个函数,实现就是重载了运算符(),这样这个类就有了类似于函数的行为,这就是仿函数。
注意:
仿函数是类不是函数,只是重载了()看上去像函数。
2、使用:
在上述向上或者向下的调整中,可以在两个节点中的比较中使用仿函数,
首先定义仿函数:
class Less
{
public:
bool operator()(const T& x, const T& y)
{
return x < y;
}
};
template<class T>
class Greator
{
public:
bool operator()(const T& x, const T& y)
{
return x > y;
}
};
接着在priority_queue这个类的模版参数中多加一个模版参数来控制大于还是小于,
template<class T,class Container = vector<T>,class Compare = Less<T>>
这样的话,如果在参数中给less或者不给,就建立大堆,
如果给greater就建立小堆
三、反向迭代器的实现:
在库里面,反向迭代器是封装正向迭代器来实现的,如上图,正向迭代器的begin是反向迭代器的end,正向迭代器的end是反向迭代器的begin
注意:
在实现解引用中,解引用的是当前位置的下一个位置,判断的是正常判断的,如果不是解引用的下一个位置的话,那么就会在rend的数据访问不到。
其余都封装正向迭代器实现
namespace ppr
{
template<class Iterator,class Ref ,class Ptr>
struct ReverseIterator
{
typedef ReverseIterator<Iterator, Ref, Ptr> Self;
ReverseIterator(Iterator it)
:_it(it)
{}
Ref operator*()
{
Iterator tmp = _it;
return *(--tmp);
}
Ptr operator->()
{
return &(operator*());
}
Self& operator++()
{
--_it;
return *this;
}
Self& operator--()
{
++_it;
return *this;
}
bool operator!=(const Self& lt) const
{
return _it != lt._it;
}
bool operator==(const Self& lt) const
{
return _it == lt._it;
}
Iterator _it;
};
}