栈知识点详解(数据结构,严慧敏版)

来源:互联网 发布:下载小林铜排计算软件 编辑:程序博客网 时间:2024/06/06 02:58

1.栈结构:

typedf struct{SElemType *base;SElemType *top;int stacksize;}SqStack

2.对栈进行操作的函数
//此栈内元素为int#include<stdio.h>#include<errno.h>#include"stdlib.h"#include"StackOp.h"#define InitStackSize 100//初始化栈void InitStack(SqStack &s){s.base = (int *)malloc(InitStackSize * sizeof(int));if (!s.base)exit;s.top = s.base;s.stacksize = InitStackSize;printf("初始化成功\n");}//若栈不为空,则删除栈顶元素,并将其返回给e。int PoP(SqStack &s, int &e){if (s.top == s.base)return 0;e = *(--s.top);return 1;}//插入新的元素为栈顶int Push(SqStack &s, int e){if (s.top-s.base>=s.stacksize){s.base = (int *)realloc(s.base, (s.stacksize + 1)*sizeof(int));if (!s.base)exit(EOVERFLOW);s.top = s.base + s.stacksize;s.stacksize++;}*s.top = e;s.top++;return 1;}//返回栈的长度int StackLength(SqStack s){int *p;int L=0;if (s.base >= s.top)return 0;p = s.base;while (p<s.top){L++;p++;}return L;}//销毁栈void DestroyStack(SqStack &s ){free(s.base);}//清空栈void ClearSrack(SqStack &s){s.top = s.base;     //top 与 base之间的元素才是有效元素}//遍历栈void StackTraverse(SqStack &s){int *p;p = s.base;while (p<s.top){printf("%d",*p);p++;}}


(2)4*4迷宫  寻找出口
//迷宫求解,通过方向优先级:右-下-上-左void MazePath(){int p = 0;    //p表示当前位置int i = 0, j = 0;SqStack s;InitStack(s);//构建迷宫,1表示可以通过,0表示不可以通过,2表示已经经过int a[4][4] = { { 1, 1, 0, 0 },                 { 1, 0, 1, 0 },           { 1, 1, 1, 1 },           { 0, 1, 0, 1 }};a[0][0] = 2;Push(s,p);while (p < 33){printf("%d\n",p);i = p / 10; j = p % 10;//获取当前位置if (a[i][j + 1] == 1 && (j + 1 <= 3) && i <= 3){p = i * 10 + j + 1;Push(s, p);a[i][j + 1] = 2;}else if (a[i + 1][j] == 1 && (i + 1 <= 3) && (j <= 3)){p = (i + 1) * 10 + j;Push(s, p);a[i + 1][j] = 2;}else if (a[i - 1][j] == 1 && (i - 1 >= 0) && (j <= 3)){p = (i - 1) * 10 + j;Push(s, p);a[i - 1][j] = 2;}else if (a[i][j - 1] == 1 && (j - 1 >= 0) && (i <= 3)){p = i * 10 + j - 1;Push(s, p);a[i][j - 1] = 2;}i = p / 10; j = p % 10;//获取当前位置if ((j == 3 || a[i][j + 1] != 1) && (i == 3 || a[i + 1][j] != 1) && (j == 0 || a[i][j - 1] != 1) && (i == 0 || a[i - 1][j] != 1)&&p!=33){PoP(s, p);printf("%d\n",p);PoP(s,p);Push(s,p);}}}
上面我用P表示位置,例如P=23,就代表着在a[2][3]的位置
(3)汉诺塔问题求解
//汉诺塔求解void Hanio(int n,SqStack &x,SqStack &y,SqStack &z){if (n==1){Move(x,1,z);}else{Hanio(n-1,x,z,y);Move(x,n,z);Hanio(n-1,y,x,z);}}void Move(SqStack &x, int n,SqStack &z){int e;PoP(x,e);Push(z,e);}


(4)运算表达式求值(严蔚敏 数据结构 书上的,这里是实现方式)
以下是运算符号优先级

我这里把#用=替换了
1)先是处理字符的栈及相关操作,基本同上面一样
#include<stdio.h>#include<errno.h>#include"stdlib.h"#include"StackOp_C.h"#define InitStack_C_Size 100void InitStack_C(SqStack_C &s){s.base = (char *)malloc(InitStack_C_Size * sizeof(char));if (!s.base)exit;s.top = s.base;s.stacksize = InitStack_C_Size;printf("初始化成功\n");}int Push_C(SqStack_C &s, char e){if (s.top - s.base >= s.stacksize){s.base = (char *)realloc(s.base, (s.stacksize + 1)*sizeof(char));if (!s.base)exit(EOVERFLOW);s.top = s.base + s.stacksize;s.stacksize++;}*s.top = e;s.top++;return 1;}int PoP_C(SqStack_C &s, char &e){if (s.top == s.base)return 0;e = *(--s.top);return 1;}char GetTop_C(SqStack_C &s){char c='a';c = *(--s.top);s.top++;return c;}
2)然后正式开始

//计算求值void EvaluateExpression(SqStack_C &OPTR,SqStack &OPND){char c[100];char *p; char op='a';        //暂时保存操作符int a, b;       //暂时保存操作数gets_s(c); p = c;Push_C(OPTR,'=');while (*p != '=' || GetTop_C(OPTR)!='='){if (IsChar(*p)){Push(OPND,(*p-48));p++;}else{char n = Precede(GetTop_C(OPTR), *p);switch (n){case '>':PoP_C(OPTR,op);PoP(OPND, a); PoP(OPND,b);Push(OPND,Operate(op,a,b));break;case '<':Push_C(OPTR, *p); p++;break;case '=':PoP_C(OPTR,op);p++;break;default:break;}}}}

判断是字符还是数字的函数
bool IsChar(char c){if (c >= 48 && c <= 57)return true;else return false;}

判断运算符优先级函数
char Precede(char top,char c){switch (top){case '+':case '-':if (c == '+' || c == '-' || c == ')' || c == '='){return '>';}else{return '<';}break;case '*':case '/':if (c == '('){return '<';}else{return '>';}break;case '(':if (c == ')'){return '=';}else{return '<';}break;case ')':return '>';break;case '=':if (c == '='){return '=';}else{return '<';}break;default:break;}}
计算结果
//计算结果int Operate(char c,int a,int b){switch (c){case '+':return (b+a);break;case '-':return b - a;break;case '*':return b*a;break;case '/':return b / a;break;default:return  0;break;}}


运行结果测试



有错误的地方还请指正,没写过多少。

(5)波兰式转逆波兰表达式
//这里用的调用的函数还是(4)中的函数,只是将EvaluateExpression稍做修改
代码如下
//将普通式转换为逆波兰式void InverseBoLan(SqStack_C &OPTR, SqStack_C &OPND){char c[100];char *p;char op = 'a';        //暂时保存操作符int a, b;       //暂时保存操作数gets_s(c);p = c;Push_C(OPTR, '=');while (*p!='='||GetTop_C(OPTR)!='='){if (IsChar(*p)){Push_C(OPND,*p);p++;}else{switch (Precede(GetTop_C(OPTR),*p)){case '>':PoP_C(OPTR,op);Push_C(OPND,op);break;case '<':Push_C(OPTR,*p);p++;break;case '=':PoP_C(OPTR,op);p++;break;default:break;}}}a = Stack_CLength(OPND);for (int i = a; i >0; i--){PoP_C(OPND,op);c[i] = op;}for (int i = 1; i <= a;i++){printf("%c",c[i]);}}
运行截图:











原创粉丝点击