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

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 100
void 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]);
	}
}
运行截图:











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值