09 栈的应用_中缀表达式转后缀表达式20220611

听黑马程序员教程《基础数据结构和算法 (C版本)》,

照着老师所讲抄的,

视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1

喜欢的朋友可以去看看,欢迎大家一起交流学习。

09 栈的应用_中缀表达式转后缀表达式20220611_main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include "LinkStack.c" typedef struct MYCHAR{
LinkNode* node;
char* pAddres; // 放字符地址,因为每个字符都有一个地址。
int index; // 记录位置
}MyChar; // 判断是否是数字
int IsNumber(char c){
return c >='0' && c <='9';
} // 输出数字
void NumberOperate(char* p){
printf("%c",*p);
} // 判断是否左括号和右括号
int IsLeft(char c){
return c == '(';
}
int IsRight(char c){
return c == ')';
} // 判断是否运算符号
int IsOperator(char c){
return c=='+' || c=='-' || c=='*' || c=='/';
}
// 返回运算符的优先级
int GetPriority(char c){
if(c=='*' || c == '/'){
return 2;
}
if(c=='+'|| c=='-'){
return 1;
}
return 0;
} // 创建MyChar
MyChar* CreateMyChar(char* p){
MyChar* mychar = (MyChar*)malloc(sizeof(MyChar));
mychar->pAddres = p;
return mychar;
} // 左括号进栈
void LeftOperate(LinkStack* stack,char* p){
Push_LinkStack(stack,(LinkNode*)CreateMyChar(p));
} // 右括号操作 弹出并输出,直到匹配左括号
void RightOperate(LinkStack* stack){
// 先判断栈中有没有元素,有则弹,
while(Size_LinkStack(stack)>0){
MyChar* mychar = (MyChar*)Top_LinkStack(stack);
// 如果匹配左括号,则出栈
if(IsLeft(*(mychar->pAddres))){
Pop_LinkStack(stack);
break;
}
// 不匹配左括号,则输出,弹出
printf("%c",*(mychar->pAddres));
Pop_LinkStack(stack);
free(mychar);
}
} // 运算符号的操作
void OperatorOperator(LinkStack* stack,char* p){
// 先取出栈顶符号
MyChar* mychar = (MyChar*)malloc(sizeof(MyChar));
if(mychar==NULL){
Push_LinkStack(stack,(LinkNode*)CreateMyChar(p));
return;
}
// 如果栈顶优先级低于当前字符的优先级,则直接入栈
if(GetPriority(*(mychar->pAddres))< GetPriority(*p)){
Push_LinkStack(stack,(LinkNode*)CreateMyChar(p));
return;
}
// 如果优先级不低,
else{
while(Size_LinkStack(stack) > 0){
MyChar* mychar2 = (MyChar*)malloc(sizeof(MyChar));
// 如果优先级低,当前符号入栈
if(GetPriority(*(mychar2->pAddres))<GetPriority(*p)){
Push_LinkStack(stack,(LinkNode*)CreateMyChar(p));
break;
}
// 输出
printf("%c",*(mychar2->pAddres));
// 弹出
Pop_LinkStack(stack);
// 释放
free(mychar2); } } } int main(){
printf("好好学习,天天向上~!\t\t\t 09_栈的应用_中缀表达式转后缀表达式20220611\n\n\n"); char* str ="8+(3-1)*5";
char* p = str; // 创建栈
LinkStack* stack = Init_LinkStack(); while(*p !='\0'){
// 如果是数字,直接输出
if(IsNumber(*p)){
// 直接输出
NumberOperate(p);
} // 如果是左括号,进栈
if(IsLeft(*p)){
LeftOperate(stack,p);
} // 如果是右括号,则将栈顶符号弹出并输出,直到匹配左括号
if(IsRight(*p)){
RightOperate(stack);
} // 如果是运算符号
if(IsOperator(*p)){
OperatorOperator(stack,p);
} p++;
} while(Size_LinkStack(stack)>0){ MyChar* mychar = (MyChar*)Top_LinkStack(stack);
printf("%c",*(mychar->pAddres));
Pop_LinkStack(stack);
free(mychar); }
// 以上输出结果为 831-5*+
printf("\n\n");
system("pause");
return 0;
}

LinkStack.c

 1 #ifndef LINKSTACK_H
2 #define LINKSTACK_H
3
4 #include <stdio.h>
5 #include <stdlib.h>
6
7
8 // 链式栈的节点
9 typedef struct LINKNODE{
10 struct LINKNODE* next;
11 }LinkNode;
12
13 // 链式栈
14
15 typedef struct LINKSTACK{
16 LinkNode HeadNode; //头节点
17 int size;
18 }LinkStack;
19
20 // 初始化
21 LinkStack* Init_LinkStack();
22 // 入栈
23 void Push_LinkStack(LinkStack* stack,LinkNode* data);
24 // 出栈 (删除第一个元素)
25 void Pop_LinkStack(LinkStack* stack);
26 // 返回栈顶元素
27 LinkNode* Top_LinkStack(LinkStack* stack);
28 // 返回栈元素的个数
29 int Size_LinkStack(LinkStack* stack);
30 // 清空栈
31 void Clear_LinkStack(LinkStack* stack);
32 // 销毁栈
33 void FreeSpace_LinkStack(LinkStack* stack);
34
35
36
37 #endif

LinkStack.h

 1 #include "LinkStack.h"
2
3
4 // 初始化
5 LinkStack* Init_LinkStack(){
6
7 // 开内存
8 LinkStack* stack = (LinkStack*)malloc(sizeof(LinkStack));
9 // 初始化
10 stack->HeadNode.next = NULL;
11 stack->size = 0;
12
13 return stack;
14 }
15
16 // 入栈
17 void Push_LinkStack(LinkStack* stack,LinkNode* data){
18
19 if(stack == NULL){
20 return;
21 }
22 if(data == NULL){
23 return;
24 }
25
26 data->next = stack->HeadNode.next;
27 stack->HeadNode.next = data;
28
29 stack->size++;
30
31 }
32
33 // 出栈 (删除第一个元素)
34 void Pop_LinkStack(LinkStack* stack){
35
36 if(stack == NULL){
37 return ;
38 }
39 if(stack->size==0){
40 return ;
41 }
42
43 // 第一个有效节点
44 LinkNode* pNext = stack->HeadNode.next;
45 stack->HeadNode.next = pNext->next; // pNext.next为第一个有效节点的下一个节点
46
47 stack->size--;
48
49 }
50
51 // 返回栈顶元素
52 LinkNode* Top_LinkStack(LinkStack* stack){
53
54 if(stack == NULL){
55 return NULL;
56 }
57 if(stack->size==0){
58 return NULL;
59 }
60
61 return stack->HeadNode.next;
62 }
63
64 // 返回栈元素的个数
65 int Size_LinkStack(LinkStack* stack){
66 if(stack == NULL){
67 return -1;
68 }
69 return stack->size;
70 }
71
72 // 清空栈
73 void Clear_LinkStack(LinkStack* stack){
74
75 if(stack == NULL){
76 return;
77 }
78 stack->HeadNode.next = NULL;
79 stack->size=0;
80
81 }
82
83 // 销毁栈
84 void FreeSpace_LinkStack(LinkStack* stack){
85
86 if(stack == NULL){
87 return;
88 }
89
90 free(stack);
91
92
93 }

C语言- 基础数据结构和算法 - 09 栈的应用_中缀表达式转后缀表达式20220611的更多相关文章

  1. C语言- 基础数据结构和算法 - 08 栈的应用_就近匹配20220611

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  2. C语言- 基础数据结构和算法 - 栈的链式存储

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  3. C语言- 基础数据结构和算法 - 栈的顺序存储

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  4. C语言- 基础数据结构和算法 - 队列的顺序存储

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  5. C语言- 基础数据结构和算法 - 循环链表

    听黑马程序员教程<基础数据结构和算法 (C版本)>,照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友可 ...

  6. C语言 - 基础数据结构和算法 - 企业链表

    听黑马程序员教程<基础数据结构和算法 (C版本)>,照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友可 ...

  7. C语言 - 基础数据结构和算法 - 单向链表

    听黑马程序员教程<基础数据结构和算法 (C版本)>,照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友可 ...

  8. C语言- 基础数据结构和算法 - 动态数组

    听黑马程序员教程<基础数据结构和算法 (C版本)>,照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友可 ...

  9. 大数据技术之_16_Scala学习_13_Scala语言的数据结构和算法_Scala学习之旅收官之作

    第十九章 Scala语言的数据结构和算法19.1 数据结构(算法)的介绍19.2 看几个实际编程中遇到的问题19.2.1 一个五子棋程序19.2.2 约瑟夫问题(丢手帕问题)19.2.3 其它常见算法 ...

随机推荐

  1. Spring理解1 ioc

    Spring Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器(框架).   需要了解 ioc容器 IOC底层原理 IOC接口 BeanFactory Bean的作用域 IOC操 ...

  2. Python接口自动化——文件上传/下载接口

    〇.前言 文件上传/下载接口与普通接口类似,但是有细微的区别. 如果需要发送文件到服务器,例如:上传文档.图片.视频等,就需要发送二进制数据,上传文件一般使用的都是 Content-Type: mul ...

  3. 什么是机器学习的分类算法?【K-近邻算法(KNN)、交叉验证、朴素贝叶斯算法、决策树、随机森林】

    1.K-近邻算法(KNN) 1.1 定义 (KNN,K-NearestNeighbor) 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类 ...

  4. OpenHarmony 3.1 Beta版本关键特性解析——HAP包安装实现剖析

    ​(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点)​ 石磊 随着社会的不断发展,人们逐渐注重更加高效.舒适.便捷.有趣的生活和工作体验. OpenAtom OpenHa ...

  5. .NET MAUI RC 是完整的 API 并准备好起飞 (GA)

    2022年4月12日 微软发布了 .NET Multiplatform App UI (.NET MAUI) 作为候选版本RC ,具体参见 https://devblogs.microsoft.com ...

  6. ASP.NET Core 6.0 添加 JWT 认证和授权

    序言 本文将分别介绍 Authentication(认证) 和 Authorization(授权). 并以简单的例子在 ASP.NET Core 6.0 的 WebAPI 中分别实现这两个功能. 相关 ...

  7. Jmeter监控平台搭建:JMeter+InfluxDB+Grafana

    背景 平时一般用Jmeter的Gui模式,添加对应的插件,查看每秒线程数.TPS.响应时间等曲线,其实高并发是不建议这么看的. 解决方案 可以搭配InfluxDB+Grafana工具,使Jmeter异 ...

  8. element.insertAdjacentHTML

    一.概念 insertAdjacentHTML() 方法将指定的文本解析为 Element 元素,并将结果节点插入到DOM树中的指定位置.它不会重新解析它正在使用的元素,因此它不会破坏元素内的现有元素 ...

  9. Nginx下载文件指定文件名称

    配置 location ^~/TEMP/ { alias/share/files/; if ($request_uri ~* ^.*\/(.*)\.(txt|doc|pdf|rar|gz|zip|do ...

  10. Java并发编程之Lock(同步锁、死锁)

    这篇文章是接着我上一篇文章来的. 上一篇文章 同步锁 为什么需要同步锁? 首先,我们来看看这张图. 这是一个程序,多个对象进行抢票. package MovieDemo; public class T ...