【考研】栈和栈的应用
因为今年考研的原因,所以就根据王道后面的习题进行总结
大致归类了一些顺序、链表存储结构、基本算法实现代码合集,也是为了后续方便复习
1.1顺序栈
1.1.1结点结构
#define MaxSize 50 //定义栈中元素的最大个数
typedef struct
{ElemType data[MaxSize] ;//存放栈中元素 int top ;//栈顶指针ElemType base; //栈底指针int StackSize // 栈长
}SqStack; //顺序栈的简写
1.1.2基本操作
(1)初始化
//初始化顺序栈,构造一个空栈
void InitSqStack (SqStack &S){S.top = -1; //初始化栈顶指针
}
(2)空栈
bool StackEmpty(SqStack S){if(s.top == -1) return true ;else return false ;
}
(3)满栈
//判断是否为满栈
void judgeFull(SqStack &s){if(s.top-s.base == s.StackSize){printf("栈满!\n");}else{printf("栈未满!\n");}
}
(4)入栈
bool Push(SqStack &S , ElemType x){if(S.top == MaxSize-1) return false ;S.data[++top] = x ; return true ;
}
(5)出栈
bool Pop(SqStack &S,ElemType &x) {if(S.top == -1) return false ;x = S.data[top--] ;return true ;
}
(6)读取栈顶元素
bool Pop(SqStack &S , ElemType &x){if(s.top == 1)return false;x = S.data[top];return true;
}
1.2链表栈
1.2.1结点结构
typedef struct SNode
{ElemType data ;//存放栈中元素 struct SNode *next ; //栈顶指针
}SNode , *SLink; //链栈的结点 typedef struct LinkStack
{Slink top ; //栈顶指针 int count ; //链栈结点数
}LinkStack, *SqStack; //链栈
1.2.2基本操作
(1)进栈
bool Push(LinkStck &S , ElemType x){SLink p = (Slink*)malloc(sizeof(Slink));//给新元素分配空间p->data = x; //新元素的值p->next = S->top; //p的后继指向栈顶元素S->top = p; //栈顶指针指向新的元素S->count++; //栈中元素个数加1return true;
}
(2)出栈
bool Pop(LinkStack *S , ElemType &x) {if(S->top == NULL) return false ;x = S->top->data ; //栈顶元素值 Slink p = S->top ; //辅助指针 S->top = S->top->next ; //栈顶指针后移free(p); //释放被删除数据的存储空间 S->count-- ; //栈中元素个数减一 return true ;
}
1.3共享栈
1.3.1数据结构
#define MaxSize 100 //定义栈中元素的最大个数
typedef struct{ElemType daata[MaxSize]; //存放栈中元素int top1; //栈1栈顶指针int top2; //栈2栈顶指针
}SqDoubleStack; //顺序共享栈的缩写
1.3.2基本操作
(1)进栈
bool Push(SqDoubleStack &S ,ElemType x , int stackNum){if(S.top1+1 == S.top2)return false; //栈满if(stackNum == 1) //栈1有元素进栈S.data[++top1] = x;else(stackNum == 2) //栈2有元素进栈S.data[--top2] =x;return true;
}
——————————————————————————————————————————————————
——————————————————————————————————————————————————
int push(int i , elemType x){
//入栈,i为栈号,i=0表示左边的s1栈,i=1表示右边的s2栈,x是入栈元素
//入栈成功则返回1,否则返回0 if(i<0 ||i>1){printf("栈号输入不对\n");exit(0); }if(S.top1 - S.top2 = 1){printf("栈已满\n")exit(0);}switch(i){case 1 : S.data[++top1];return 1;break;case 2 : S.data[++top2];return 1;}
}
(2)退栈
int pop(int i){
//退栈算法,i代表栈号,i=0时s1栈,i=1时为s2栈
//退栈成功则返回退栈元素,否则返回-1 if(i<0 || i>1){printf("栈号输入错误\n");exit(0);} switch(i){case 0:if(top1 == -1 ){printf("栈空\n");exit(-1);}elsereturn S.data[top1 --];case 1:if(top2 == MaxSize){printf("栈空\n");return -1;}elsereturn S.data[top2++];}
}
2.算法
2.1判断是否为合法序列
I为进栈,O为出栈,计算入栈出栈的次数,进行对比来判断,序列为A数组。
bool JudgeStck(char A[]){int i=0; //记录数组的下标 int j=0; //记录入栈次数 int k=0; //出栈的次数 while(A[i] != '\0'){switch(A[i]){case 'I' j++ ; break; //入栈加1 case 'O' k++ ; break; //出栈加1 if(k>j)return false;}i++;}if(j != k){printf("非法序列\n");return false;}elseprintf("合法序列\n");return true;
}
2.2链表是否中心对称
int compareStack(LinkList &L , int n){
//L是具有带头结点的带n个元素的单链表,本算法检测是否中心对车 int i; //记录栈里面的数值 char s[n/2]; //s字符栈LNode *p = L->next; //p是工作指针,指向待处理的元素 for(i = 0 ; i<n/2 ;i++){//链表前一半入栈 s[i] = p->data;p = p->next;} i--; //恢复到最后的i值if(n%2 == 1 ) //若链表是奇数链,则后移中心点 p = p->next;while( p!= NULL && s[i] ==p->data){ //检测是否是中心对称 i--;p = p->next;} if(i == -1) //栈为空栈 return 1; //中心对称 else //非空 return 0; //中心不对称
}
2.3两个栈模仿队列:入队,出队
入队
bool Enqueue(SqStack &S1,SqStack &S2 , int x){//S1入队,S2出队 if( !JudgeFull(S1)){ //确保S1非满才能弹出 Push(S1 , x);return 1; }if(JudgeFull(S1) && !StackEmpty(S2)){printf("栈满\n");return 0; }if(StackEmpty(S2) && !JudgeFull(S1) ){while(!StackEmpty(S1)){Pop(S1 , x);Push(S2 ,x);}}Push(S1 ,x);return 1;
}
出队
bool DeQueue(SqStack &S1 , SqStack &S2 , int x){if(!StackEmpty(S2)){Pop(S2 , x);}else if(StackEmpty(S1)){printf("队空\n");}else{while(!StackEmpty(S1)){Pop(S1 ,x);Push(S2 , x);}Pop(S2 ,x):}
}
2.4括号匹配
bool Check(char *str){Stack s ;InitStck(s) ;int len = strlen(str) ; //字符串长度为len for (int i = 0; i<len ; i++){char a = str[i] ;swith(a){case '(':case '[':case '{':Push(s,a) ;break ;case ')':if(Pop(s) != '(' ) return false ; //出栈顶。如果不匹配直接返回不合法 break ;case ']':if(Pop(s) != '[' ) return false ;break ;case '}':if(Pop(s) != '{' ) return false ;break ;}}if(Empty(s)) return true ;//匹配完所有括号最后要求栈中为空 else return false ;
}
2.5火车变轨换座问题
void Train_Arranger(char *train){
//用train表示火车H为硬座,S为软座char *p = train , *q = train , c;SqStack S;InitStack(S);while(*p){if( p == 'H'){Push(S , p); //把H存入栈中 }else*(q++) = *p; //把S接在前部 p++;}while(!StackEmty(S)){Pop(S , c);*(p++) = *c; //把H接在后部 }
}
非递归运算——用栈实现
struct Recursion {int no; //保存nint val; //保存Pn(x)值
};
struct Stack {Recursion *arr;int len;int top;
};
int getP(Stack *s,int n,int x) {//该算法函数,传入栈,n和xif (n==0) {return 1;}int fv1 = 1, fv2 = 2*x;for (int i = n; i >= 2;i--) {//将序号入栈,从上至下,从2到ns->top++;s->arr[s->top].no = i;}while (s->top>=0) {//边出栈边计算s->arr[s->top].val = 2 * x*fv2 - 2 * (s->arr[s->top].no - 1)*fv1;fv1 = fv2;fv2 = s->arr[s->top].val;s->top--;}return fv2;
【考研】栈和栈的应用相关推荐
- 天勤考研数据结构笔记—栈的C语言实现
栈的基本概念 栈的定义:栈是一种只能在一端进行插入或删除操作的线性表.其中允许进行插入或删除的一端称为栈顶(top).栈顶是由一个称为栈顶指针的位置指示器(其实就是一个变量,对于顺序栈,就是数组索引, ...
- c语言中缀表达式求值_数据结构考研笔记之栈与队列(四)栈与队列应用括号匹配、中缀表达式转前缀后缀问题...
文字:独木 排版:独木 图片:独木 栈与队列 1.括号匹配问题 栈 例题1 例题2-----不匹配例题1 例题3-----不匹配例题2 2. 表达式求值问题 例题 1.中缀表达式转前缀表达式 2.中缀 ...
- 数据结构与算法(3-1)栈(顺序栈、两栈共享空间、链栈、栈的计算器)
目录 一.顺序栈 存储结构 总代码 二.两栈共享空间 存储结构: 总代码: 三.链栈 存储结构: 总代码: 一.顺序栈 存储结构: 栈特点:先进后出,后进先出.(特殊的线性表) 入栈时在栈顶添加元素, ...
- linux存储--进程栈 线程栈 内核栈 中断栈(十六)
一.栈是什么?栈有什么作用? 首先,栈 (stack) 是一种串列形式的 数据结构.这种数据结构的特点是 后入先出 (LIFO, Last In First Out),数据只能在串列的一端 (称为:栈 ...
- 【Android 逆向】x86 汇编 ( push / pop 入栈 / 出栈 指令 | ret / retn 函数调用返回指令 | set 设置目标值指令 )
文章目录 一.push / pop 入栈 / 出栈 指令 二.ret / retn 函数调用返回指令 三.set 设置目标值指令 总结 一.push / pop 入栈 / 出栈 指令 push / p ...
- 什么是栈,栈存储结构详情
什么是栈,栈存储结构详情 同顺序表和链表一样,栈也是用来存储逻辑关系为一对一数据的线性存储结构,如图所示: 从图1我们看到,栈存储结构与之前学的线性存储有所差异,这源于栈对数存和取的过程有特殊的要求: ...
- 栈劫持(栈迁移)介绍
栈劫持 栈劫持也可以称为栈迁移,用来解决栈本身可以利用的空间不够用,一般是溢出空间不够 用,没办法有效构造rop链.这个时候我们可以通过劫持ebp的方式,利用leave 和 ret两个汇编指令来做 到 ...
- 算法练习day8——190326(队列实现栈、栈实现队列)
1.仅用队列结构实现栈结构 1.1 分析: 1.所有数先入data队列: 2.将前n-1个数入help队列,弹出最后一个数: 3.将help中的前n-2个数入data队列,弹出最后一个数: 4.重复2 ...
- JVM【带着问题去学习 02】数据结构栈+本地方法栈+虚拟机栈+JVM栈运行原理
1.数据结构栈 栈是一种比较简单的数据结构,后进先出.栈本身是一个线性表,但是这个表中只有一端允许数据的进出.栈的常用操作包括入栈push和出栈pop,对应于数据的压入和弹出.由于栈后进先出的特性,常 ...
最新文章
- 自动化运维工具之puppet简单实用
- [Google Guava] 使用和避免null
- bzoj 2908. 又是nand(树链剖分+区间NAND+单点修改)
- TCP面向连接中的“连接”和“可靠”与“不可靠”
- JM与h264标准中的关键字说明
- Cannot resolve jakarta.validation:jakarta.validation-api:2.0.2
- solr之搭建企业搜索平台,配置文件详细solrconfig.xml
- Prototype使用Template
- 固态硬盘开卡软件_SATAFIRM S11 MSATA固态硬盘刷固件
- XP框架管理器EdXposed v4.6.2 (46200)
- 生信技能树linux虚拟机,【生信技能树】Linux练习
- 2012考研数学二第(18)题——多元函数积分学:二重积分求面积+画曲线:心形线
- TweenMax之一些方法
- Unity中的警告--warning CS0108:'XXXX' hides inherited member 'AAAAA'. Use...的原因以及解决办法
- 前端H5新增标签和CSS3高级
- python 声音基频f0_ASR中常用的语音特征之FBank和MFCC(原理 + Python实现)
- 旅游地理学期末(大学)
- 联想拯救者Y7000加装内存条
- 10_行销(Marketing)里客户流失
- 有趣的网站:河蟹娱乐