一 stack
template <class T,class Sequence = deque<T>>
class stack
{
// 判断 2 个 stack 是否相等/小于
friend bool operator== __STL_NULL_TMPL_ARGS(const stack&,const stack&);
friend bool operator< __STL_NULL_TMPL_ARGS(const stack&,const stack&);
public:
// stack 直接拿配接器内的类型用
typedef typename Sequence::value_type value_type;
typedef typename Sequence::size_type size_type;
typedef typename Sequence::reference reference;
typedef typename Sequence::const_reference const_reference;
protected:
// 配接器
Sequence c;
public:
// 判空/元素个数/栈顶元素/入栈/弹栈
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
reference top() { return c.back(); }
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_back(); }
};
template<class T,class Sequence>
bool operator==(const stack<T,Sequence>& x,const stack<T,Sequence>& y)
{
// 配接器 == 配接器
return x.c == y.c;
}
template<class T,class Sequence>
bool operator<(const stack<T,Sequence>& x,const stack<T,Sequence>& y)
{
// 配接器 < 配接器
return x.c < y.c;
}
二 queue
template <class T,class Sequence = deque<T>>
class queue
{
// 判断 2 个 stack 是否相等/小于
friend bool operator== __STL_NULL_TMPL_ARGS(const queue&,const queue&);
friend bool operator< __STL_NULL_TMPL_ARGS(const queue&,const queue&);
public:
// queue直接拿配接器内的类型用
typedef typename Sequence::value_type value_type;
typedef typename Sequence::size_type size_type;
typedef typename Sequence::reference reference;
typedef typename Sequence::const_reference const_reference;
protected:
// 配接器
Sequence c;
public:
// 判空/元素个数/栈顶元素/入栈/弹栈
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
reference front() { return c.front(); }
const_reference front() const { return c.front(); }
reference back() { return c.back(); }
const_reference back() const { return c.back(); }
void push(const value_type& x) { return c.push_back(x); }
void pop() { c.pop_front(); }
};
template<class T,class Sequence>
bool operator==(const queue<T,Sequence>& x,const queue<T,Sequence>& y)
{
// 配接器 == 配接器
return x.c == y.c;
}
template<class T,class Sequence>
bool operator<(const queue<T,Sequence>& x,const queue<T,Sequence>& y)
{
// 配接器 < 配接器
return x.c < y.c;
}
三 priority_queue
template <RandomAccessIterator>
// 堆插入
inline void push_heap(RandomAccessIterator first,RandomAccessIterator last)
{
// 调用该接口时,已经有新元素插入到了末尾
// 迭代器首/尾 元素距离类型 元素类型
__push_heap_aux(first,last,distance_type(first),value_type(first));
}
template <RandomAccessIterator,class Distance,class T>
inline void __push_heap_aux(RandomAccessIterator first,RandomAccessIterator last,
Distance*,T*)
{
// 迭代器首 指向最后一个元素的下标 下标 0 最后一个元素
__push_heap(first,Distance((last - first) - 1),Distance(0),T(*(last - 1)));
}
template <RandomAccessIterator,class Distance,class T>
void __push_heap(RandomAccessIterator first,Distance holeIndex,Distance topIndex,T value)
{
// 根据孩子节点求父节点 (index - 1) / 2
Distance parent = (holeIndex - 1) / 2;
// 如果孩子节点下标至少大于 0 ,并且父节点小于新插入尾部的元素
while(holeIndex > topIndex && *(first + parent) < value)
{
// 让孩子节点 == 父节点,这里没有直接交换,也能达到交换的效果
// 只要条件满足,尾部节点就会一直被移动,那么可以直接最开始就把尾部节点值拷贝保存起来
// 最后结束循环在在孩子节点上赋值即可
*(first + holeIndex) = *(first + parent);
// 更新孩子节点
holeIndex = parent;
// 重新计算父子节点
parent = (holeIndex - 1) / 2;
}
// 最后在让孩子节点 = 最开始尾部从插入的值
*(first + holeIndex) = value;
}
template <class RandomAccessIterator>
inline void pop_heap(RandomAccessIterator first,RandomAccessIterator last,T*)
{
__pop_heap_aux(first,last,value_type(first));
}
template <class RandomAccessIterator,class T>
inline void __pop_heap_aux(RandomAccessIterator first,RandomAccessIterator last,T*)
{
__pop_heap(first,last - 1,last - 1,T(*(last - 1),distance_type(first));
}
template <class RandomAccessIterator,class T,class Distance>
inline void __pop_heap(RandomAccessIterator first,RandomAccessIterator last,
RandomAccessIterator result,T value,Distance*)
{
// 尾部 = 头部元素
*result = *first;
__adjust_heap(first,Distance(0),Distance(last - first),value);
}
template <class RandomAccessIterator,class Distance,class T>
void __adjust_heap(RandomAccessIterator first,RandomAccessIterator holeIndex,
Distance len,T value)
{
// 原数组尾元素不计入
// 0
Distance top_Index = holeIndex;
// 右孩子节点
DIstance secondChild = 2 * holeIndex + 2;
// 孩子节点 < 最大长度
while(secondChile < len)
{
// 左比右大 -- 孩子节点
if(*(first + secondChild) < *(first + (secondChild - 1)))
secondChild--;
// 孩子赋值给父
*(first + holeIndex) = *(first + secondChild);
// 更新孩子,父节点
// 此时父是空洞节点,即无效节点
holeIndex = secondChild;
secondChild = 2 * (secondChild + 1);
}
// 如果叶子节点只有左节点,边界处理
if(secondChild == len)
{
*(first + holeIndex) = *(first + (secondChild - 1));
holeIndex = secondChild - 1;
}
// 最后父节点就是空洞节点,在该节点上进行向上调整,结束给空洞节点赋值
__push_heap(first,holeIndex,topIndex,value);
}
template <class T,class Sequence = vector<T>,
class Compare = less<typename Sequence::value_type>>
class priority_queue
{
public:
// priority_queue直接拿配接器内的类型用
typedef typename Sequence::value_type value_type;
typedef typename Sequence::size_type size_type;
typedef typename Sequence::reference reference;
typedef typename Sequence::const_reference const_reference;
// 配置器/比较方法
protected:
Sequence c;
Compare comp;
// 无参构造/自定义比较函数构造
public:
priority_queue() :c() {}
explicit priority_queue(const Compare& x) :c(),comp(x) {}
// 迭代器区间制造和自定义比较方法
template <class InputIterator>
priority_queue(InputIterator first,InputIterator last,const Compare& x)
:c(first,last)
,comp(x)
{ make_heap(c.begin(),c.end(),comp); }
// 迭代器区间构造
template <class InputIterator>
priority_queue(InputIterator first,InputIterator last)
:c(first,last)
{ make_heap(c.begin(),c.end(),comp); }
// 判空/元素总个数/堆顶元素/插入/删除
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
const_reference top() const { return c.front(); }
void push(const value_type& x)
{
// 看上面
__STL_TRY
{
c.push_back(x);
push_heap(c.begin(),c.end(),comp);
}
// 异常处理
__STL_UNWIND(c.clear();)
}
void pop()
{
// 看上面
__STL_TRY
{
pop_heap(c.begin(),c.end(),comp);
}
// 异常处理
__STL_UNWIND(c.clear());
}
};