思想:
数字:直接输出
左括号:直接入栈(默认优先级最低)
右括号:将栈顶元素输出,直到遇到左括号。
运算符:1:若一开始没有比较的话直接进栈 2:若栈顶元素优先级低,进栈 3:若栈顶元素优先级高,将栈顶元素弹出并输出,直到低就进栈。
举例:char str="8+(3-1)*5"
遇到数字8直接输出,刚开始栈没有元素,+直接进栈,左括号直接进栈,3输出,-跟栈顶元素优先级比较,栈顶(优先级低,-入栈,1输出,遇到右括号),将栈顶元素输出并弹出,直到遇到左括号匹配。*跟栈顶元素+比较,优先级高,直接入栈,5输出。最后栈还剩*+,依次输出弹出。
代码实现:
头文件.h
#pragma once
#include <iostream>
using namespace std;
//运用企业链表构建
typedef struct SNode {
struct SNode* next;
}Snode;
typedef struct LinkStack {
int size;
Snode head;//小挂钩
}Lstack;
//初始化
Lstack* init_Lstack();
//增加
void push_Lstack(Lstack* Lsta, Snode* data);
//删除
void pop_Lstack(Lstack* Lsta);
//返回栈顶元素
Snode* Top_Lstack(Lstack* Lsta);
//摧毁内存
void free_Lstack(Lstack* Lsta);
//返回栈的大小
int Size_Lstack(Lstack* Lsta);
.cpp文件
#include "Selink_stack.h"
Lstack* init_Lstack()
{
Lstack* lsta = (Lstack*)malloc(sizeof(Lstack));
lsta->size = 0;
lsta->head.next = NULL;
return lsta;
}
void push_Lstack(Lstack* Lsta, Snode* data)
{
if (Lsta == NULL) {
cout << "链表未被创建!" << endl;
}
data->next = Lsta->head.next;
Lsta->head.next = data;
Lsta->size++;
}
void pop_Lstack(Lstack* Lsta)
{
if (Lsta == NULL) {
cout << "链表未被创建!" << endl;
}
Snode* first = Lsta->head.next;
Lsta->head.next = first->next;
Lsta->size--;
}
Snode* Top_Lstack(Lstack* Lsta)
{
return Lsta->head.next;
}
void free_Lstack(Lstack* Lsta)
{
if (Lsta == NULL) {
cout << "链表未被创建!" << endl;
}
free(Lsta);
cout << "链表已被摧毁!" << endl;
}
int Size_Lstack(Lstack* Lsta)
{
return Lsta->size;
}
主函数测试文件
#include "Seq_linkStack.h"
typedef struct Mychar {
Snode node;
char *p;//存放入栈的信息
}mychar;
//判断是否为数字
bool isnumber(char p) {
if (p >= '0' && p <= '9')
return true;
else return false;
}
bool isleft(char p) {
return p =='(';
}
bool isright(char p) {
return p == ')';
}
//判断是否遇到运算符
bool isoperator(char p) {
if (p == '+' || p == '-' || p == '*') {
return true;
}
else return false;
}
//优先级判断
int getoper(char p) {
if (p == '+' || p == '-')
return 1;
if (p == '*' || p == '/')
return 2;
if (p == '(' || p == ')')
return 0;
}
void test() {
//栈的创建
Lstack* lst = init_Lstack();
//定义中缀表达式
char str[] = "8+(3-1)*5";
char* p = str;
//转化过程
while ((*p) != '\0') {
//遇到数字直接输出
if (isnumber(*p)) {
cout<<*p;
}
//遇到左括号入栈
if (isleft(*p)) {
mychar* data = (mychar*)malloc(sizeof(mychar));
data->p = p;
push_Lstack(lst,(Snode*)data);
}
//遇到右括号
if (isright(*p)) {
while (lst->size > 0) {
mychar* tmp = (mychar*)Top_Lstack(lst);
if (isleft(*(tmp->p))) {
//如果是左括号 结束并弹出左括号
pop_Lstack(lst);
free(tmp);
break;
}
else {
printf("%c", *tmp->p);
}
pop_Lstack(lst);
free(tmp);
}
}
//遇到运算符
if (isoperator(*p)) {
//如果栈为空时,直接进栈
mychar* tmp = (mychar*)Top_Lstack(lst);
if (tmp==NULL) {
mychar* data = (mychar*)malloc(sizeof(mychar));
data->p = p;
push_Lstack(lst,(Snode*)data);
p++;
continue;
}
//栈低
if (getoper(*(tmp->p)) < getoper(*p)) {
mychar* data1 = (mychar*)malloc(sizeof(mychar));
data1->p = p;
push_Lstack(lst,(Snode*)data1);
}
//栈高
else {
while (Size_Lstack(lst)>0) {
tmp = (mychar*)Top_Lstack(lst);
if (getoper(*(tmp->p)) >getoper(*p)) {
cout<<tmp->p;
pop_Lstack(lst);
free(tmp);
}
else {
mychar* data2 = (mychar*)malloc(sizeof(mychar));
data2->p = p;
push_Lstack(lst,(Snode*)data2);
}
}
}
}
p++;
}
//最后将栈中的元素遍历输出
while (Size_Lstack(lst) > 0) {
mychar* tmp2 = (mychar*)Top_Lstack(lst);
printf("%c", *tmp2->p);
pop_Lstack(lst);
free(tmp2);
}
cout << endl;
//销毁栈
free_Lstack(lst);
}
int main() {
test();
return 0;
}
运行效果
总结:
主函数实现功能代码逻辑还没那么熟练,有时间须得再敲一次!