11数据结构—栈的应用后缀表达式求解

该文章描述了一个使用链表数据结构实现的中缀表达式到后缀表达式的转换算法。通过栈操作处理运算符和括号,遵循运算符的优先级规则。代码包括了栈的初始化、压栈、弹栈等操作,以及对数字、括号和运算符的判断处理。最后通过主函数测试了整个算法的逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思想:

数字:直接输出
左括号:直接入栈(默认优先级最低)
右括号:将栈顶元素输出,直到遇到左括号。
运算符: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;
}

运行效果

总结:

主函数实现功能代码逻辑还没那么熟练,有时间须得再敲一次! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值