#include <iostream>
#include <stack>
#include <vector>
#include <list>
#include <queue>
#include <functional> // greater 算法头文件
// stack :
// stack() : 构造栈
// empty() : 检测栈是否为空
// size() : 返回栈中元素个数
// top() : 返回栈顶元素的引用
// push() : 将元素val 压入stack中
// pop() : 将stak 中尾部元素弹出
// 最小栈!
#if 0
class MinStack {
public:
void push(int x) {
elem.push(x);
if (min.empty() || x < min.top) {
min.push(x);
}
else {
min.push(min.top());
}
}
void pop() {
min.pop();
elem.pop();
}
int top() {
return elem.top();
}
int getMin() {
return min.top();
}
private:
std::stack<int> elem;
std::stack<int> min;
};
#endif
// 栈的压入弹出序列
#if 0
class Solution {
public:
bool IsPopOrder(std::vector<int> pushV, std::vector<int> popV) {
std::stack<int> stack;
int idx = 0;
for (int val : pushV) {
stack.push(val);
while (!stack.empty() && popV[idx] == stack.top()) {
stack.pop();
idx++;
}
}
return idx == popV.size();
}
};
#endif
// 逆波兰表达式求值
#if 0
class Solution {
public:
int evalRPN(vector<string>& tokens) {
std::stack<int> stack;
for (auto& s : tokens) {
if (!(s == "+" || "-" == s || "*" == s || "/" == s)) {
stack.push(atoi(s.c_str()));
}
else {
int l = stack.top();
stack.pop();
int r = stack.top();
stack.pop();
switch (s[0]) {
case '+':stack.push(l + r); break;
case '-':stack.push(r - l); break;
case '*':stack.push(l*r); break;
case '/':stack.push(r / l); break;
}
}
}
return stack.top();
}
};
#endif
// 两个栈实现队列
#if 0
class MyQueue {
public:
MyQueue() {
}
void push(int x) {
stk1.push(x);
}
int pop() {
if (stk2.empty()) {
while (!stk1.empty()) {
stk2.push(stk1.top());
stk1.pop();
}
}
int pop = stk2.top();
stk2.pop();
return pop;
}
int peek() {
if (stk2.empty()) {
while (!stk1.empty()) {
stk2.push(stk1.top());
stk1.pop();
}
}
return stk2.top();
}
bool empty() {
return stk1.empty() && stk2.empty();
}
private:
std::stack<int> stk1;
std::stack<int> stk2;
};
#endif
// 栈的模拟实现
namespace pz {
template<class T>
class stack {
public:
stack(){}
void push(const T& x) { _c.push_back(x); }
void pop() { _c.pop_back(); }
T& top() { return _c.back(); }
const T& top() const { return _c.back(); }
size_t size() { return _c.size(); }
bool empty() { return _c.empty(); }
private:
std::vector<T> _c;
};
}
// queue :
// 队列是一种容器适配器,专门用于在FIFO中操作;
// empty() : 检测队列是否为空
// size() : 返回队列中有效元素的个数
// front() : 返回对头元素的引用;
// back() : 返回对尾元素的引用;
// push_back() : 在队列尾部如队列;
// pop_front() : 在对头部出队列;
// 队列模拟实现:
namespace pz {
template <class T>
class queue {
public:
queue() {}
void push(const T& x) { _c.push_back(x); }
void pop() { _c.pop_front(); }
T& back() { return _c.back(); }
const T& back() { return _c.back(); }
T& front() { return _c.front(); }
const T& front() const { return _c.front(); }
size_t size()const { return _c.size(); }
bool empty() const { return _c.empty(); }
private:
std::list<T> _c;
};
}
// 用队列模拟实现栈
class MyStack {
public:
void push(int x) {
if (q1.empty() || q1.size() <= q2.size()) {
q1.push(x);
while (!q2.empty()) {
q1.push(q2.front());
q2.pop();
}
}
else {
q2.push(x);
while (!q1.empty()) {
q2.push(q1.front());
q1.pop();
}
}
}
int pop() {
int pop = -1;
if (q1.empty()) {
pop = q2.front();
q2.pop();
}
else {
pop = q1.front();
q1.pop();
}
return pop;
}
int top() {
if (q1.empty()) {
return q2.front();
}
else {
return q1.front();
}
}
bool empty() {
return q1.empty() && q2.empty();
}
private:
std::queue<int> q1;
std::queue<int> q2;
};
// priority_queue : 优先队列;(默认是大顶堆,java默认是小堆)
// priority_queue() / priority_queue(first,last) : 构造一个空的优先队列!
// empty() : 检测优先队列是否为空
// top() : 返回优先队列的堆顶!
// push(x) : 在优先队列中插入元素x
// pop() : 删除堆顶!
void TestPrirortyQueue() {
// 默认情况像创建的是大堆!
std::vector<int>v{ 3,2,7,6,0,4,8,9,5 };
std::priority_queue<int> q1;
for (auto& e : v) {
q1.push(e);
std::cout << q1.top() << " ";
}
std::cout << std::endl;
// 如果要创建小堆,将第三个模板参数换成greater比较方式
std::priority_queue<int, std::vector<int>, std::greater<int>> q2(v.begin(), v.end());
std::cout << q2.top() << std::endl;
}
class Date {
public:
Date(int _year = 2022, int _month = 7, int _day = 19) :year(_year), month(_month), day(_day){}
bool operator<(const Date& d) const {
return year < d.year || (year == d.year && month < d.month) || (year == d.year && month == d.month && day < d.day);
}
bool operator>(const Date& d) const {
return year > d.year || (year == d.year && month > d.month) || (year == d.year && month == d.month && day > d.day);
}
friend std::ostream& operator<< (std::ostream& _cout, const Date& d) {
_cout << d.year << "-" << d.month << "-" << d.day << std::endl;
return _cout;
}
private:
int year;
int month;
int day;
};
void TestPriorityQueue1() {
// 大堆 需要类自定义类提供 < 重载!
std::priority_queue<Date> q1;
q1.push(Date(2019, 8, 27));
q1.push(Date(2018, 8, 27));
q1.push(Date(2015, 8, 27));
std::cout << q1.top() << std::endl;
// 小堆 需要自定义类提供 > 重载!
std::priority_queue<Date, std::vector<Date>, std::greater<Date>> q2;
q2.push(Date(2019, 8, 27));
q2.push(Date(2018, 7, 27));
q2.push(Date(2015, 6, 27));
std::cout << q2.top() << std::endl;
}
#if 0
int main() {
TestPrirortyQueue();
TestPriorityQueue1();
return 0;
}
#endif
#if 0
// 模拟实现 priority_queue
namespace pz {
template<class T>
struct less {
bool operator()(const T& left, const T& right) {
return letf < right;
}
};
template<class T>
struct greater {
bool operator()(const T& left, const T& right) {
return left > right;
}
};
template<class T, class Container = std::vector<T>, class Compare = less<T>>
class priority_queue {
public:
priority_queue() :c() {};
template<class Iterator>
priority_queue(Iterator first, Iterator last):c(first,last) {
int count = c.size();
int root = ((count - 2) >> 1);
for (; root <= 0; root--) {
AdjustDown(root);
}
}
void push(const T& data) {
c.push_back(data);
AdjustUp(c.size() - 1);
}
void pop() {
if (empty()) return;
swap(c.front(), c.back());
c.pop_back();
AdjustDown(0);
}
size_t size() const {
return c.size();
}
bool empty() {
return c.empty();
}
const T& top() const {
return c.front();
}
private:
// 向上调整
void AdjustUp(int child) {
int parent = ((child - 1) >> 1);
while (child) {
if (Compare()(c[parent], c[child])) {
swap(c[child], c[parent]);
child = parent;
parent = ((child - 1) >> 1);
}
else {
return;
}
}
}
// 向下调整
void AdjustDown(int parent) {
int child = parent * 2 + 1;
while (child < c.size()) {
// 找以parent 为根较大的孩子!
if (child + 1 < c.size() && Compare()(c[child], c[child + 1])) {
child += 1;
}
// 检测双亲是否满足情况!
if (Compare()(c[parent], c[child])) {
swap(c[child], c[parent]);
parent = child;
child = parent * 2 + 1;
}
else {
return;
}
}
}
private:
Container c;
};
}
#endif
// 容器适配器
// 适配器是一种设计模式,该模式是将一个类的接口转换成客户希望的零位一个接口
// stl 中 stack 和 queue 默认使用 deque;
// deque原理
// deque 是一种双开口的连续空间的数据结构!
// deque 并不是真正的连续空间,而是有一段段连续的小空间拼接而成,实际deque类似与一个动态的二维数组!
// 用deque 来模拟实现一波stack 和 queue
#if 0
#include <deque>
namespace pz {
template <class T,class Collection=std::deque<T>>
class stack {
public:
stack() {};
void push(const T& x) { c.push_back(x); }
void pop() { c.pop_back(); }
T& top() { return c.back(); }
const T& top() const { return c.back(); }
size_t size() const { return c.size(); }
bool empty() const { return c.empty(); }
private:
Collection c;
};
template<class T,class Collection=std::deque<T>>
class queue {
public:
queue() {}
void push(const T& x) { c.push_back(x); }
void pop() { c.pop_front(); }
T& back() {
return c.back()
}
const T& back() const { return c.back(); }
T& front() { return c.front(); }
const T& front() const { return c.front(); }
size_t size() const {
return c.size();
}
bool empty() const {
return c.empty();
}
private:
Collection c;
};
}
#endif ```
自学C++ day07 stack && queue
最新推荐文章于 2024-07-12 10:56:01 发布