数据结构—栈

栈定义:

仅限在标为进行插入删除操作的线性表

栈顶为表尾,栈底为表头


栈的操作性质:

先入后出

  1. 操作序列问题:
  • 已知入栈序列与操作序列:
    入栈序列1,2,3,4
    操作序列PPQPQQPPQQ
    求出栈序列(直接模拟)

  • 已知入栈序列和出栈序列求操作序列:
    模拟

  • 已知入栈序列, 什么样的出栈序列是不可能的:
    求解方法\(1\):
    出栈序列看作\(1...n\)的一个排列, 设为\(p_{1}p_{2}...p_{n}\),若存在\(i < j < k\)使得:\(p_{j} < p_{k} < p_{i}\),该序列不合法

口诀:312

求解方法\(2\):
依次检查所给的出栈序列:\(p_{1} ... p_{n}\)
对于\(p_{1}\),对应入栈序列\(p_{1}\)之前都必须入栈...
直至推出矛盾


栈的实现

线性表

struct Stack{
	int *data;
	int bufferlen;
	int top;
}

初始化及撤销:

  1. 初始化\(top = 0\)表示为空栈, 这里\(top\)表示将要插入元素位置
int InitStack(Stack &S, int n)
{
	S.data = new int[n];
	S.bufferlen = n;
	S.top = 0;
	return 0;
}

int DestoryStack(Stack &S)
{
	delete []S.data;
	S.datas = nullptr;
	S.bufferlen = 0;
	S.top = 0;
	return 0;
}

链表实现

  1. 初始化:

PS:栈的链表实现不需要头结点

int Init(Stack &S)
{
	S = nullptr;
	return 0;
}

int Delete(Stack &S)
{
	while (!Is_empty(S))
		Pop(S);
	return 0;
}
  1. 判断是否为空
int Is_empty(Stack &S)
{
	if (S == nullptr)
		return 1;
	return 0;
}
  1. 入栈及出栈操作
int Push(Stack &S, int x)
{
	Stack p = new struct SNode;
	p -> data = x;
	p -> next = S;
	S = p;
	return 0;
}

int Pop(Stack &S)
{
	Stack p = S;
	S = S->next;
	delete p;
	return 0;
}

int Top(Stack &S)
{
	return S->data;
}

应用

栈的操作代码实现

栈的操作问题

进制转换

算法3-1:八进制数

括号匹配问题

问题 I: 括号匹配问题

表达式计算

  1. 算符优先顺序: \(*、/\) \(>\) \(+、-\)
  2. 括号优先顺序:先算括号内的,再算括号外的:
  • \((op\): \(op\)优先级高
  • \(op(\): \((\)优先级高
  • \()op\): \()\)优先级高
  • \(op)\): \(op\)优先级高

\(()\)相遇,括号内运算结束

  1. 从左到右运算
posted @ 2022-01-03 20:35  lhqwd  阅读(105)  评论(0)    收藏  举报