栈(数据结构篇)

ops/2024/10/18 18:13:31/

数据结构篇之栈

栈(stack)

概念

  • 栈(stack)是限制插入和删除只能在一个位置上的进行的表,而这个模型唯一的开口位置是表的末端,叫做栈顶(top),相反表的首部,叫做栈底。对于栈的基本操作有Push(进栈)Pop(出栈),前者相当于插入,后者则是删除表中最后一个元素(也就是处在栈顶位置的元素)。
  • 栈是一个先进后出的模型

注意事项

  • 虽然这里将栈放在线性表外,但是栈模型也属于线性表。

  • 是既可以用数组实现也可以用链表实现

    • 如果栈的大小已知且固定,或者对随机访问元素效率有较高要求,使用数组实现栈可能更合适。
    • 如果栈的大小不确定,或者插入和删除操作频繁且在栈顶之外发生,使用链表实现栈可能更有优势。

image

链表实现代码

struct Node{int data;Node *next;
};
typedef Node* Stack;Stack createStack(int data){struct Node* p=new struct Node;p->data=data;p->next=NULL;return p;
}//进栈
void Push(Stack &head,int data){Stack add= createStack(data);if(head==NULL){head=add;}else{Node* p=head;add->next=p;head=add;}
}//出栈
void Pop(Stack &head){if(head==NULL){cout<<"栈中没有数据"<<endl;return;}Node* p=head;head=p->next;delete p;
}//获取栈顶元素
int top(Stack head){return head->data;
}//打印栈
void printStack(Stack head){if(head==NULL){cout<<"栈中没有数据"<<endl;return;}Node* p=head;while (p!=NULL){cout<<p->data<<" ";p=p->next;}cout<<endl;
}//获取栈的大小
int Size(Stack head){Node* p=head;int cnt=0;if(p->data&&p->next==NULL){cnt=1;} else{while (p!=NULL){cnt++;p=p->next;}}return cnt;
}//判断栈是否为空
bool empty(Stack head){if (head!=NULL){return false;}else{return true;}
}//清空栈
void destroy(Stack &head){if(head==NULL){cout<<"栈中没有数据"<<endl;return;}Node* tail=head->next;while (head!=NULL){delete head;head=tail;if(tail!=NULL)tail=tail->next;elsereturn;}
}

数组实现代码:

class stack{
public://入栈void Push(int data){head.push_back(data);}//出栈void Pop(){if(head.empty()){cout<<"栈中没有数据!"<<endl;return;} elsehead.pop_back();}//获取栈顶元素int top(){if(head.empty()){cout<<"栈中没有数据!"<<endl;return NULL;}return head.back();}//打印栈void printstack(){if(head.empty()){cout<<"栈中没有数据"<<endl;return;}else{for(vector<int>::const_iterator it=head.end()-1;it>=head.begin();it--){cout<<*it<<" ";}cout<<endl;}}//清空栈void destory(){head.clear();}//获取栈的大小int Size(){return head.size();}//判断栈是否为空bool empty(){if(head.empty()){return true;} else{return false;}}
private:vector<int>head;
};

逆波兰转换式

概念

  • 一种后缀表达式,例如a+b+c*d,转换成逆波兰表达式就为:a b + c d * +,然后我们将逆波兰表达式压入栈中(将元素压入栈中遇到运算符号就将栈中的两个元素进行出栈在进行运算,运算完后再压入栈中,重复操作就能得到逆波兰表达式的结果),逆波兰表达式中没有括号!

  • 转换成逆波兰表达式,需要一个空栈跟一个临时输出区(但不直接输出),将运算元素放进临时输出区,将运算符号压入栈中。

    • 如果运算符的优先级大于上一个运算符,就进行入栈。
    • 如果运算符的优先级小于等于上一个运算符,就将前面的运算符出栈放在临时输出区,再将该运算符入栈。
    • 如果栈中有左括号,后面入栈的运算符不是右括号的话,左括号就不出栈,而是继续重复上两个规则,直到右括号出现就将左括号出栈,但括号不放入临时输出区
    • 当运算元素都放入临时输出区时,栈区还有运算符就直接出栈放入临时存放区,最终将临时存放区按顺序输出出来就是转换的逆波兰表达式

代码

bool flag(char a,char b){int a1,b1;if(a=='+'||a=='-'){a1=1;}else if(a=='*'||a=='/'){a1=2;}else if(a=='('||a==')'){a1=3;}if(b=='+'||b=='-'){b1=1;}else if(b=='*'||b=='/'){b1=2;}else if(b=='('||b==')'){b1=3;}return a1>=b1;
}vector<char> reversePolan(char *an,int len){stack<char>s;vector<char>v;int cnt=0;for(int i=0;i<len;i++){if(an[i]!='+'&&an[i]!='-'&&an[i]!='*'&&an[i]!='/'&&an[i]!='('&&an[i]!=')'){v.push_back(an[i]);}else if(an[i]=='+'||an[i]=='-'||an[i]=='*'||an[i]=='/'||an[i]=='('||an[i]==')'){if(s.empty()){s.push(an[i]);}else if(an[i]=='('){s.push(an[i]);cnt=1;}else if(an[i]==')'&&cnt==1){while (s.top()!='('){v.push_back(s.top());s.pop();}s.pop();cnt=0;} else if(flag(s.top(),an[i])){while (!s.empty()){if(s.top()=='('){break;}v.push_back(s.top());s.pop();}s.push(an[i]);}else{s.push(an[i]);}}}if(!s.empty()){while (!s.empty()){v.push_back(s.top());s.pop();}}return v;
}int main() {char an[]={'a','+','b','*','c','+','(','d','*','e','+','f',')','*','g'};int len= sizeof(an)/ sizeof(an[0]);auto a= reversePolan(an,len);for(char i:a){cout<<i<<" ";}cout<<endl;system("pause");return 0;
}

尾言

完整版笔记也就是数据结构与算法专栏完整版可到我的博客进行查看,或者在github库中自取(包含源代码)

  • 博客1: codebooks.xyz
  • 博客2:moonfordream.github.io
  • github项目地址:Data-Structure-and-Algorithms

http://www.ppmy.cn/ops/52271.html

相关文章

计算机组成原理-第6章计算机的运算方法

6.1无符号数和有符号数 6.1.1无符号数 没有符号&#xff0c;在寄存器中的每一位均可用来存放数值。 6.1.2有符号数 1&#xff0c;机器数与真值&#xff1a;0表示正&#xff0c;1表示负。 把符号数字化的数称为机器数&#xff0c;而把带或-符号的数称为真值。 2&#xff0…

抽卡机小程序:设计与开发全攻略

在移动互联网时代&#xff0c;小程序以其轻便、易用、无需安装的特点&#xff0c;迅速成为用户日常使用的重要工具。其中&#xff0c;抽卡机小程序因其独特的娱乐性和互动性&#xff0c;受到广大用户的喜爱。本文将为大家详细介绍抽卡机小程序的设计与开发全攻略。 一、需求分析…

ARM功耗管理软件之软件栈及示例

安全之安全(security)博客目录导读 思考&#xff1a;功耗管理软件栈及示例&#xff1f;WFI&WFE&#xff1f;时钟&电源树&#xff1f;DVFS&AVS&#xff1f; SoC底层软件低功耗系统设计与实现-CSDN直播 ARM功耗管理精讲与实战汇总参见&#xff1a;Arm功耗管理精讲与…

越复杂的CoT越有效吗?Complexity-Based Prompting for Multi-step Reasoning

Complexity-Based Prompting for Multi-step Reasoning 论文&#xff1a;https://openreview.net/pdf?idyf1icZHC-l9 Github&#xff1a;https://github.com/FranxYao/chain-of-thought-hub 发表位置&#xff1a;ICLR 2023 Complexity-Based Prompting for Multi-step Reason…

前端面试题(基础篇七)

一、谈谈你对webpack的看法 webpack是一个模块打包工具&#xff0c;我们可以使用webpack管理我们的模块依赖&#xff0c;编译输出模块所需的静态文件。它可以很好的管理、打包web开发中所需的html、css、JavaScript以及其他各种静态文件&#xff08;使用的图片、字体图标等&am…

23.并发

目录 一、一些概念二、进程和线程2.1 概念2.2 多线程导致的问题2.3 使用spawn创建新线程2.4 线程与move闭包 三、消息传递3.1 概念3.2 创建通道3.3 示例3.4 其它测试 四、共享状态并发4.1 互斥器4.2 Mutex的API4.3 多线程共享Mutex1&#xff09;在多线程之间共享值&#xff1b;…

SCI一区级 | Matlab实现BO-Transformer-LSTM多变量时间序列预测

SCI一区级 | Matlab实现BO-Transformer-LSTM多变量时间序列预测 目录 SCI一区级 | Matlab实现BO-Transformer-LSTM多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.【SCI一区级】Matlab实现BO-Transformer-LSTM多变量时间序列预测&#xff0c;贝叶斯…

【windows|005】系统分区介绍

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 ​ &#x1f3c5;阿里云ACE认证高级工程师 ​ &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社…