开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 20 天,点击查看活动详情。
一、单向链表-企业级版本
-
结点 只维护指针域 不维护数据域
-
用户数据 需要预留出4个字节空间 给底层链表使用
-
对链表 提供对外接口
-
初始化链表
-
插入链表
-
遍历链表
-
删除链表
-
销毁链表
单向链表-企业级版本设计思路
二、栈的顺序存储 ---- 利用数组
-
栈 属于 先进后出的数据结构
-
初始化栈
init -
入栈
push -
出栈
pop -
访问栈顶元素
top -
返回栈大小
size -
判断栈是否为空
isEmpty -
销毁栈
destroy
栈的基本结构
栈的顺序存储
三、栈的链式存储 ---- 利用链表
- 和顺序存储的对外接口完全一样
栈的链式存储设计思路图
四、栈的应用- 就近匹配案例
-
扫描字符串
-
准备栈
-
如果是左括号 ---- 入栈
-
如果是右括号
-
栈是否为空
-
如果不为空 出栈
-
如果为空 立即停止 并且报错
-
-
遍历所有字符后 ,判断栈是否为空
-
如为空 没问题
-
如果不为空 报错 左括号没有匹配到对应的右括号
-
-
销毁栈
栈的应用-就近匹配案例解析图
示例程序
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "seqStack.h"
/*
从第一个字符开始扫描
当遇见普通字符时忽略,
当遇见左括号时压入栈中
当遇见右括号时从栈中弹出栈顶符号,并进行匹配
匹配成功:继续读入下一个字符
匹配失败:立即停止,并报错
结束:
成功: 所有字符扫描完毕,且栈为空
失败:匹配失败或所有字符扫描完毕但栈非空
*/
//判断字符是否是左括号
int IsLeft(char ch)
{
return ch == '(';
}
//判断字符是否是右括号
int IsRight(char ch)
{
return ch == ')';
}
void printError(char * str, char * errMsg,char * pos)
{
printf("错误的信息:%s\n", errMsg);
printf("%s\n", str);
//计算打印空格数量
int num = pos - str;
for (int i = 0; i < num; i++)
{
printf(" ");
}
printf("A\n");
}
void test01()
{
char * str = "5+5*(6)+9/3*1-(1+3(";
char * p = str;
//初始化栈
seqStack stack = init_SeqStack();
while ( *p != '\0')
{
//如果是左括号 入栈
if (IsLeft(*p))
{
push_SeqStack(stack, p);
}
//如果是右括号 弹出栈中的栈顶元素
if (IsRight(*p))
{
//如果栈的元素个数>0 说明 可以匹配
if (size_SeqStack(stack)>0)
{
//弹出栈顶元素
pop_SeqStack(stack);
}
else //空栈 匹配失败
{
printError(str, "右括号没有匹配到左括号",p);
break;
}
}
p++;
}
//判断栈是否为空栈
while ( size_SeqStack(stack) > 0)
{
printError(str, "左括号没有匹配到右括号", top_SeqStack(stack));
//弹出栈顶元素
pop_SeqStack(stack);
}
//销毁栈
destroy_SeqStack(stack);
stack = NULL;
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
五、中缀表达式和后缀表达式
-
中缀是符合人类习惯
-
后缀符合计算机使用
-
中缀如何转为后缀表达式
-
计算机如果利用后缀表达式进行计算