固定模板
#include<iostream>
#include<stdexcept>
using namespace std;
//模板声明,表明Stack类是一个通用的模板,可以用于存储任何类型的元素T
template<typename T>
//栈的声明
//Stack类的声明,表示一个栈的数据结构
class Stack {
private://定义私有(成员变量)
struct Node {//结构体定义,用于表示栈中的结点,每个结点包含一个数据成员data和一个指向下一个结点的指针next
T data;
Node* next;
Node(T d) :data(d), next(NULL) {}
};
Node* head;//用于保存栈的头结点指针
int size;//用于保存栈的大小
public://定义公共
Stack() : head(NULL), size(0) {}//构造函数,用于初始化栈,它将头结点指针设置为NULL,并将栈的大小设置为0
~Stack();//析构函数,用于释放栈所用的内存
void push(T element);//公共函数,用于将一个新元素压入栈顶
T pop();//用于从栈顶弹出一个元素
T top() const;//用于获取栈顶的元素,但不弹出它
int getSize() const;//用于获取栈中元素数量
};
//栈的扩容
//有链表实现栈时,每次如果是新生成的结点,则不涉及到像顺序表那样的扩容操作
//栈的销毁
template<typename T>
Stack<T>::~Stack() {//析构函数的声明,用于在对象销毁时,释放动态分配的结点内存
//不断循环访问栈中的元素,每次取出栈顶元素,存储到临时变量temp中,并且弹出栈顶,并利用delete将弹出的元素进行内存释放,知道栈为空为止
while (head != NULL) {
Node* temp = head;
head = head->next;
delete temp;
}
}
//入栈
template<typename T>
void Stack<T>::push(T element) {
//创建了一个新的Node对象,并将传入的元素赋值给该对象的数据成员。通过使用new操作符动态分配了内存来存储新的结点
Node* newNode = new Node(element);
newNode->next = head;//将新节点的next指针指向当前的头结点。这样,新节点就被添加到了栈的头部
head = newNode;//将头节点的指针更新为新节点,使新节点成为栈的新头部
++size;//栈大小+1
}
//出栈
template<typename T>
T Stack<T>::pop() {
if (head == NULL) {
throw std::underflow_error("Stack is empty");//如果栈空,抛出异常
}
T result = head->data;//将头结点的数据成员赋值给result变量,准备返回弹出的元素
Node* temp = head;//将头结点的指针赋值给temp变量,用于后续删除头结点
head = head->next;//将头结点的next指针赋值给头结点本身,从而将头结点从链表中移除
delete temp;//调用delete释放temp所指向的结点内存
--size;//栈大小-1
return result;//返回弹出的元素
}
//获取栈顶元素
template<typename T>
T Stack<T>::top() const {
if (head == NULL) {
throw std::underflow_error("Stack is empty");//如果栈空,抛出异常
}
return head->data;//不空,返回head的data域,即栈顶元素。
}
template<typename T>
int Stack<T>::getSize() const {
return size;
}
int main() {
return 0;
}
1.Problem - 2031
int main() {
int N, x;
while (cin >> N >> x) {
if (N == 0) {
cout << 0 << endl;
continue;
}
if (N < 0) {
cout << '-';
N = -N;
}
Stack<int> stk;
while (N) {
stk.push(N % x);
N = N / x;
}
while (stk.getSize()) {
int x = stk.pop();
if (x >= 10) {
printf("%c", 'A' + x - 10);
}
else {
printf("%d", x);
}
}
cout << endl;
}
return 0;
}
2.Problem - 2051
int main() {
int n;
while (cin >> n) {
Stack<int> stk;
while (n) {
stk.push(n % 2);
n = n / 2;
}
while (stk.getSize()) {
cout << stk.pop();
}
cout << endl;
}
return 0;
}
3.LCR 123. 图书整理 I - 力扣(LeetCode)
class Solution {
public:
vector<int> reverseBookList(ListNode* head) {
stack<int> stk;
while(head){//遍历链表,元素逐个压栈
stk.push(head->val);
head = head->next;
}
vector<int> ans;
while(!stk.empty()){
ans.push_back(stk.top());//元素弹出 插入顺序表的尾部
stk.pop();
}
return ans;
}
};
4.LCR 027. 回文链表 - 力扣(LeetCode)
class Solution {
public:
bool isPalindrome(ListNode* head) {
stack<ListNode*> stk;
ListNode* tmp = head;
//定义一个临时指针 tmp,并将其初始化为链表的头指针 head。这么做是为了在不改变 head 指针的前提下遍历链表
while(tmp){//栈 stk 中就按逆序存储了链表的所有节点
stk.push(tmp);
tmp = tmp->next;
}
while(head){
if(head->val != stk.top()->val){
//比较当前链表节点的值 head->val 和栈顶节点的值 stk.top()->val。若不相等,就说明链表不是回文链表,直接返回 false。
return false;
}
stk.pop();//若当前节点的值和栈顶节点的值相等,就把栈顶元素弹出。
head = head->next;//将 head 指针移动到下一个节点,继续比较。
}
return true;
}
};
5.1614. 括号的最大嵌套深度 - 力扣(LeetCode)
class Solution {
public:
int maxDepth(string s) {
int ret = 0,top = 0;
//ret记录括号的最大嵌套深度,初始值为 0。top用于记录当前括号的嵌套层数,初始值为 0。
for(int i = 0;i<s.size();++i){
if(s[i]=='('){
++top;
ret = max(ret,top);
}else if(s[i] == ')'){//当遍历到的字符 s[i] 是右括号 )),将当前括号的嵌套层数减 1。
--top;
}
}
return ret;
}
};
6.20. 有效的括号 - 力扣(LeetCode)
class Solution {
public:
bool isLeft(char c) {
return c == '(' || c == '[' || c == '{';
}
bool isMatch(char l,char r) {
return l == '(' && r == ')' ||
l == '['&& r == ']'||
l == '{'&& r == '}';
}
public:
bool isValid(string s){
stack<char> stk;
for(int i = 0;i<s.size();++i){
if(isLeft(s[i])){
stk.push(s[i]);
}else{
if(stk.empty()){
return false;
}
if(!isMatch(stk.top(),s[i])){
return false;
}
stk.pop();
}
}
return stk.empty();
}
};