栈和队列--栈(1)

操作受限的线性表,即限定性的数据结构

定义

(stack)是限定仅在表尾进行插入或删除操作的线性表。
栈顶(top)是表尾端。
栈底(bottom)是表头端。
基本操作

ADT Stack {
	数据对象:
	数据关系:

	基本操作:
	InitStack(&s);
	ClearStack(&s);
	StackEmpty(s);
	StackLength(s);
	GetTop(s, &e);
	Push(&s, e);
	Pop(&s, &e);
	StackTraverse(s, visit());
}ADT Stack

栈的表示和实现

顺序栈

typedef struct {
	SElemType *base;
	SEleType *top;
	int stacksize;
}SqStack;

实现

#define STACK_INIT_SIZE 100;
#define STACKINCREMENT 10;
typedef struct {
	SElemType *base;
	SElemType *top;
	int stacksize;
}SqStack;
/* 函数定义 */
Status InitStack(SqStack &s);
Status DestroyStack(SqStack &s);
Status ClearStack(SqStack &s);
Status StackEmpty(SqStack s);
int StackLength(SqStack s);
Status GetTop(SqStack s, SElemType &e);
Status Push(SqStack &s, SElemType e);
Status Pop(SqStack &s, SElemType &e);
// 从栈底到栈顶一次对栈中每个元素调用函数visit().一旦visit()失败,则操作失败
Status StackTraverse(SqStack s, Status (*visit)());		
/* 函数部分实现 */
Status InitStack(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;
	return OK;
}

Status GetTop(SqStack s, SElemType &e) {
	if(s.top == s.base) return ERROR;
	e = *(s.top - 1);
	return OK;
}

Status Push(SqStack &s, SElemType e) {
	if(s.top - s.base >= s.stacksize) {
		s.base = (SElemType *)realloc(s.base, (s.stacksize + STACKINCREMENT) * sizeof(SElemType));
		if(!s.base)  exit(OVERFLOW);
		s.top = s.base + s.stacksize;
		s.stacksize += STACKINCREMENT;
	}
	*s.top++ = e;
	return OK;
}

Status Pop(SqStack &s, SElemType &e) {
	if(s.top == s.base) return ERROR;
	e = * --s.top;
	return ok;
}

应用

数制转换

// 1348 转成8进制 2504
void conversion() {
	InitStack(s);
	scanf("%d", N);
	while(N) {
		Push(s, N%8);
		N = N/8;
	}
	while(!StackEmpty(s)) {
		Pop(s, e);
		printf("%d", e);
	}
}

括号匹配的校验
行编辑程序
迷宫求解
穷举求解

do {
	若当前位置可通,
	则 { 将当前位置插入栈顶;
		若该位置是出口位置,则结束;
		否则切换当前位置的东邻方块为新的当前位置;
		}
	否则,
		若栈不空且栈顶位置尚有其他方向未经探索,
			则设定新的当前位置为沿顺时针方向旋转找到的栈顶位置的下一相邻块;
		若栈不空但栈顶位置的四周均不可通,
			则 { 删去栈顶位置;
				若栈不空,则重新测试新的栈顶位置,
				直至找到一个可通的相邻块或出栈至栈空;
				}
	} while(栈不空);
// 结构
typedef struct {
	int ord;				// 通道块在路径上的序号
	PosType seat;			// 通道快在迷宫中的坐标位置
	int di;					// 从此通道块走向下一通道块的方向
}SElemType;

Status MazePath(MazeType maze, PosType start, PostType end) {
// 若迷宫maze中存在从入口start到出口end的通道,则求得一条存放在栈中
	InitStack(s); curpos = start;
	curstep = 1;
	do {
		if(Pass(curpos)) {
			FootPrint(curpos);
			e = (curstep, curpos, 1);
			Push(s,e);
			if(curpos == end) return TRUE;
			curpos = NextPos(curpos, 1);
			curstep++;
		}
		else {
			if(!StackEmpty(s)) {
				Pop(s,e);
				while(e.di == 4 && ! StackEmpty(s)) {
					MarkPrint(e.seat); Pop(s,e);
				}
				if(e.di < 4) {
					e.di++; Push(s,e);
					curpos = NextPos(e.seat, e.di);
				}
			}
		}
	}while(!StackEmpty(s);
	return FALSE;
}

表达式求值

运算符优先法
OperandType EvaluateExpression() {
	// 算术表达式求值的算符优先算法。设OPTR和OPND分别为运算符栈和运算数栈
	// OP为运算符集合
	InitStack(OPTR); Push(OPTR, '#');
	initStack(OPND); c = getchar();
	while(c!='#' || GetTop(OPTR)!='#') {
		if(!In(c, OP) { Push((OPND, c); c = getchar(); }
		else 
			switch(Precede(GetTop(OPTR), c)) {
				case '<':
					Push(OPTR, c); c = getchar();
					break;
				case '=':
					Pop(OPTR, x); c = getchar();
					break;
				case '>':
					Pop(OPTR, theta);
					Pop(OPND, b); Pop(OPND, a);
					Push(OPND, Operatr(a, theta, b));
					break;
			}
	}
	return GetTop(OPND);
}

栈与递归的实现

栈还有一个重要应用是在程序设计语言中实现递归。
汉诺塔问题

void hanoi(int n, char x, char y, char z)
{
	if(n==1)
		move(x, 1, z);
	else {
		hanoi(n-1, x, z, y);
		move(x, n, z);
		hanoi(n-1, y, x, z);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值