(全网最细)顺序栈详解 +实例解析
目錄
一:棧的介紹
1:什么是棧(Stack)?
2:棧的特點(diǎn)
3:棧的相關(guān)概念
1:基本概念
2:基本操作和圖示(如圖為順序棧實(shí)例)
4:棧的應(yīng)用
三:棧的表示和操作實(shí)現(xiàn)
1:棧的抽象數(shù)據(jù)結(jié)構(gòu)類(lèi)型的定義
2:主要函數(shù)介紹
3.1 (重要)順序棧的表示和操作
1:了解順序棧
?2:特殊標(biāo)志:棧空和棧滿(mǎn)
3:棧的數(shù)據(jù)類(lèi)型定義和操作
四:棧的算法 利用
1:實(shí)現(xiàn)R進(jìn)制轉(zhuǎn)換
2:實(shí)現(xiàn)后綴表達(dá)式(逆波蘭式)
一:棧的介紹
1:什么是棧(Stack)?
棧是一種常用的、重要的數(shù)據(jù)結(jié)構(gòu)
棧是一種限定插入和刪除只能在表的 "端點(diǎn)”進(jìn)行的線(xiàn)性表,此端點(diǎn)就在隊(duì)尾
如圖:只能在隊(duì)尾進(jìn)行插入或刪除
2:棧的特點(diǎn)
后進(jìn)先出LIFO
類(lèi)比:洗碗盤(pán)子 子彈彈夾子彈出列
圖示:棧就好比一個(gè)這樣的特殊容器
?心中有圖 擼碼自然神
3:棧的相關(guān)概念
1:基本概念
1:表示
”表尾(即an端)稱(chēng)為棧頂Top;表頭(即a端)稱(chēng)為棧底Base
例如:棧s=(a1, a2, ....... an-1, an)
????????a1稱(chēng)為棧底元素
????????an稱(chēng)為棧頂元素
2.邏輯結(jié)構(gòu)
與同線(xiàn)性表相同,仍為一一對(duì)應(yīng)關(guān)系。
3.存儲(chǔ)結(jié)構(gòu)
用順序棧和鏈棧存儲(chǔ)均可,但以順序棧更常見(jiàn)
4.運(yùn)算規(guī)則
只能在棧頂運(yùn)算,且訪問(wèn)結(jié)點(diǎn)時(shí)依照后進(jìn)先出(LIFO) 的原則。
5.實(shí)現(xiàn)方式
關(guān)鍵是編寫(xiě)入棧和出棧函數(shù),具體實(shí)現(xiàn)依順序棧或鏈棧的不同而不同。
2:基本操作和圖示(如圖為順序棧實(shí)例)
插入元素到棧頂(即表尾)的操作,稱(chēng)為入棧。一般表示為壓入:PUSH (x)
從棧頂(即表尾)刪除最后一個(gè)元素的操作,稱(chēng)為出棧。 一般表示為彈出:POP(X)
?
補(bǔ):如圖:棧頂指針先指向最后一個(gè)元素(a3),再實(shí)現(xiàn)出棧操作? 概括為:e=*--S.top
4:棧的應(yīng)用
■數(shù)制轉(zhuǎn)換??????????????????? ■行編輯程序
■函數(shù)調(diào)用??? ????????????????■迷宮求解
■遞歸調(diào)用的實(shí)?? ????????? ■表達(dá)式求值
■括號(hào)匹配的檢驗(yàn)???????? ■八皇后問(wèn)題
三:棧的表示和操作實(shí)現(xiàn)
1:棧的抽象數(shù)據(jù)結(jié)構(gòu)類(lèi)型的定義
補(bǔ): 解釋圖中數(shù)據(jù)關(guān)系:ai-1是ai的前驅(qū),ai是ai-1的后繼 |類(lèi)比子彈入彈 ai-1先進(jìn)入 ai后進(jìn)入
2:主要函數(shù)介紹
Status InitStack(SqStack &S) 初始化棧
Status GetTopStack(SqStack S, ElemType &e) 獲取棧頂元素,參數(shù)e存放棧頂元素的值
Status PushStack(SqStack &S, ElemType e) 進(jìn)棧,將元素e入棧
Status PopStack(SqStack &S, ElemType &e) 出棧,出棧的元素存放在參數(shù)e中
Status EmptyStack(SqStack S) 判斷棧是否為空
Status LengthStack(SqStack S) 獲取棧的實(shí)際長(zhǎng)度
Status DestroyStack(SqStack &S) 銷(xiāo)毀棧
Status StackTraverse(SqStack S) 遍歷棧,打印每個(gè)元素
3.1 (重要)順序棧的表示和操作
1:了解順序棧
補(bǔ):top指針 指向棧頂元素an的上一位的下標(biāo)位置
??????????????????????????????????????????????????????????????????? stacksize:棧的最大容量
?2:特殊標(biāo)志:棧空和棧滿(mǎn)
空棧:可以添加新元素,并且無(wú)法出棧(下溢)
棧滿(mǎn)(上溢):無(wú)法添加新元素
????????????????解決:1報(bào)錯(cuò) 2:開(kāi)辟新空間
3:棧的數(shù)據(jù)類(lèi)型定義和操作
1 順序棧的表示
#define stack_INIT_SIZE???? 100
?typedef struct {
?????? SElemType? *base;?? //棧底指針
?????? SElemType? *top;???? //棧頂指針
?????? int stacksize;?????? //棧空間 棧可用最大空間
}Sqstack;
理解:
2 順序棧的初始化
Status iniStack(Sqstack &S){
??? S.base = (SElemType*)malloc(stack_INIT_SIZE*sizeof(SElemType));
??? //S.base =new SElemType[stack_INIT_SIZE];
? ? if(!S.base) exit(OVERFLOW);
??? S.top =S.base;
??? S.stacksize=stack_INIT_SIZE;???????????? ?
}
如圖:初始化要點(diǎn) 1:棧空 top=base 2:top base 指針指向第一個(gè)元素 3:stacksize的賦值
補(bǔ):判斷棧是否為空(如上圖)
//判棧空
bool Empty(SqStack S){
??? if(S.top == -1){
??????? return true;
??? }else{
??????? return false;
??? }
}
3 棧的長(zhǎng)度
int StackLength( SqStack S){
????????return S.top - S.base;
}
?
4 清空棧
Status ClearStack(SqStack S) {
??????? if(S.base) S.top=S.base;
??????? return OK;
}
5 銷(xiāo)毀順序棧
Status DestroyStack(SqStack &S){
??????? if(S.base){
??????????????? delete S.base;
??????????????? S.stacksize = 0;
??????????????? S.top=S.base =NULL; ??????
????????}
??????? return OK;
}
銷(xiāo)毀順序棧:3步 結(jié)構(gòu)體內(nèi)部3個(gè)變量的值? 并釋放兩個(gè)指針空間的地址
6:順序棧入棧
順序棧入棧的步驟
1:是否棧滿(mǎn)(上溢),是不能添加新元素 => 2:元素e壓入棧頂 => 3:指針+1
Status push(Sqstack &S,SElemType e){
??? if(S.base-S.top==stacksize)
??????? return ERROR;
??? *S.top++=e;
??? return OK;
}
7 順序棧的出棧
順序棧出棧的步驟
1:是否棧空(下溢)=> 2:棧頂指針-1 => 3:取棧頂元素e值?
?Status pop(Sqstack &S,SElemType &e){
??? if(S.base==S.top)//等價(jià) if(StackEmpty(S))
??????? return ERROR;
??? e=*--S.top;
??? return OK;
}
四:棧的算法 利用
1:實(shí)現(xiàn)R進(jìn)制轉(zhuǎn)換
本題要求實(shí)現(xiàn)十進(jìn)制轉(zhuǎn)R(R<10 && R>0)進(jìn)制。
#include <stdio.h>
#include <malloc.h>
typedef int Status;
typedef int SElemType;
#define stack_INIT_SIZE???? 100
#define stackINCREMENT? 10
#define OK 1
#define ERROR 0
#define OVERFLOW -2
?typedef struct {
?????? SElemType? *base;?? //棧底指針
?????? SElemType? *top;???? //棧頂指針
?????? int stacksize;?????? //棧空間
}Sqstack;
Sqstack S;
Status iniStack(Sqstack &S);
Status push(Sqstack &S,SElemType x);
Status pop(Sqstack &S,SElemType &e);
void conversion(int n,int R);
int main()
{
??? int N,R;
??? scanf("%d",&N);? //輸入十進(jìn)制數(shù)
??? scanf("%d",&R);? //輸入要轉(zhuǎn)換的進(jìn)制
??? if(R<0||R>=10)? //判斷R是否合法
??? {
??????? printf("illegal input");
??????? return ERROR;
??? }
??? //printf("開(kāi)始");
??? conversion(N,R);? //進(jìn)制轉(zhuǎn)換
??? return OK;
}
/* 請(qǐng)?jiān)谶@里填寫(xiě)答案 */
Status iniStack(Sqstack &S){
??? S.base = (SElemType*)malloc(stack_INIT_SIZE*sizeof(SElemType));
//?? ?if(!S.base) exit(OVERFLOW);
??? S.top =S.base;
??? S.stacksize=stack_INIT_SIZE;???????????? ?
}
Status push(Sqstack &S,SElemType x){
??? if(S.base-S.top==stack_INIT_SIZE)
??????? return ERROR;
??? *S.top++=x;
??? return OK;
}
Status pop(Sqstack &S,SElemType &e){
??? if(S.base==S.top)
??????? return ERROR;
??? e=*--S.top;
??? return OK;
}
bool StackEmpty(Sqstack &S)
{
?? ?if (S.top == S.base) return false;
?? ?return true;
}
void conversion(int n,int R){
?? ?int e;Sqstack S;
?? ?iniStack(S);
//?? ?printf("開(kāi)始");
??? //printf("%d",n);
??? while(n>=R){
??????? push(S,n%R);
??????? n/=R;
??????? //printf("%d",n);
??? }
??? push(S,n);
?? // printf("push結(jié)束");
??? while(S.base!=S.top){
??????? pop(S,e);
??????? printf("%d",e);
??? }
}
2:實(shí)現(xiàn)后綴表達(dá)式(逆波蘭式)
在一行中輸入一個(gè)以回車(chē)結(jié)束的非空后綴表達(dá)式,回車(chē)不屬于表達(dá)式的一部分,操作數(shù)和運(yùn)算符都以空格分隔,運(yùn)算數(shù)為不超過(guò)100的正整數(shù),運(yùn)算符僅有+、-、*、/ 四種,題目保證輸入的是合法的后綴表達(dá)式形式。
#include <stdio.h>
#include <malloc.h>
#include <iostream>
using namespace std;
typedef int Status;
typedef int SElemType;
#define stack_INIT_SIZE???? 3000000
#define stackINCREMENT? 10
#define OK 1
#define ERROR 0
#define OVERFLOW -2
?typedef struct {
????? long long int? *base;?? //棧底指針
????? long long? int? *top;???? //棧頂指針
?????? int stacksize;?????? //棧空間
}Sqstack;
Sqstack S;
Status iniStack(Sqstack &S){
??? S.base = (long long int*)malloc(stack_INIT_SIZE*sizeof(long long int));
//?? ?if(!S.base) exit(OVERFLOW);
??? S.top =S.base;
??? S.stacksize=stack_INIT_SIZE;???????????? ?
}
Status push(Sqstack &S,long long int x){
??? if(S.base-S.top==stack_INIT_SIZE)
??????? return ERROR;
??? *S.top++=x;
??? return OK;
}
Status pop(Sqstack &S,long long int &e){
??? if(S.base==S.top)
??????? return ERROR;
??? e=*--S.top;
??? return OK;
}
bool StackEmpty(Sqstack &S)
{
?? ?if (S.top == S.base) return false;
?? ?return true;
}
void conversion(int n,int R){
?? ?long long int e;Sqstack S;
?? ?iniStack(S);
//?? ?printf("開(kāi)始");
??? //printf("%d",n);
??? while(n>=R){
??????? push(S,n%R);
??????? n/=R;
??????? //printf("%d",n);
??? }
??? push(S,n);
?? // printf("push結(jié)束");
??? while(S.base!=S.top){
??????? pop(S,e);
??????? printf("%d",e);
??? }
}
int A(char* str)
{
??? int i = 0;
??? Sqstack Numbers;
??? iniStack(Numbers);
??? SElemType number_to_push;
?? ?long long int num1, num2;
??? while (str[i] != '\0') {
??????? if (str[i] != ' ') {
??????????? if (str[i] >= '0' && str[i] <= '9') {
??????????????? number_to_push = 0;
??????????????? while (str[i] != ' ' && str[i]) {
??????????????????? number_to_push = number_to_push * 10 + (str[i] - '0');
??????????????????? i++;
??????????????? }
??????????????? push(Numbers, number_to_push);
??????????? } else {
??????????????? pop(Numbers, num2);
??????????????? pop(Numbers, num1);
??????????????? switch (str[i]) {
??????????????? case '+': {
??????????????????? num1 += num2;
??????????????????? break;
??????????????? }
??????????????? case '-': {
??????????????????? num1 -= num2;
??????????????????? break;
??????????????? }
??????????????? case '*': {
??????????????????? num1 *= num2;
??????????????????? num1=num1%1000000007;
??????????????????? break;
??????????????? }
??????????????? case '/': {
??????????????????? num1 /= num2;
??????????????????? break;
??????????????? }
??????????????? case '%': {
??????????????????? num1 %= num2;
??????????????????? break;
??????????????? }
??????????????? }
??????????????? push(Numbers, num1%1000000007);
??????????? }
??????? }
??????? i++;
??? }
??? pop(Numbers, num1);
??? return num1;
}
int main(){
??????? Sqstack S;
??????? iniStack(S);
??????? int num1;
??????? char num[300000];
//?????? scanf("%s",&num);
?????? gets(num);
?? ??? ?//cin.getline(num,300000);
?????? printf("%s",num);
??????? num1=A(num);
??????? printf("%d",num1);
}
?? ?
?????? ?
總結(jié)
以上是生活随笔為你收集整理的(全网最细)顺序栈详解 +实例解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 压电加速度传感器的结构原理详解
- 下一篇: 什么是低代码开发平台,为什么会引起IT从