自学C++ day07 stack && queue

#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 ```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值