目录
1、反转链表
/*
* 一般不建议像下面这样写,我是图省事,直接用之前的代码
* e = (ElemTYpe)tmp;
* tmp->next = (SNode *) Top(S);
* 最好在栈的数据结构中定义struct Node *类型的变量
*/
void ReverseList(SList *LL,SList S){
ElemTYpe e;
SNode *tmp = *LL;
//将链表的地址全部压入栈中
while (tmp != NULL){
e = (ElemTYpe)tmp;
Push(e,&S);
tmp = tmp->next;
}
//拿到链表的最后一个地址
tmp = (SNode *) Top(S);
*LL = tmp;
Pop(&S);
//依次拿到后续地址
while(IsEmpty(S) != 1){
tmp->next = (SNode *) Top(S);
Pop(&S);
tmp = tmp->next;
}
tmp->next = NULL;
}
2、检查括号是否匹配
void Match(SList S,char *exp) {
char e;
while (*exp != '\0') {
e = *exp;
exp++;
switch (e) {
case '(':
case '[': {
Push((int) e, &S);
break;
}
case ')': {
if (IsEmpty(S) !=1 && (char) Top(S) == '('){
Pop(&S);
break;
}
else{
printf("括号匹配错误\n");
return;
}
}
case ']': {
if ( IsEmpty(S) !=1 &&(char) Top(S) == '[' ){
Pop(&S);
break;
}
else{
printf("括号匹配错误\n");
return;
}
}
}
}
if (IsEmpty(S)) {
printf("括号匹配正确\n");
}
else{
printf("括号匹配错误\n");
}
}
3、中缀Infix,前缀prefix,后缀suffix
中缀表达式 变 后缀表达式
中缀表达式 变 前缀表达式
图片来源:https://www.bilibili.com/video/BV1Fv4y1f7T1?p=20
视频的思路非常清晰,就是没代码
4、中缀表达式 转 后缀表达式
//优先级高的运算符一定是放在前面的
void InfixToSuffix(SList S,char *infix_exp,char *Suffix_exp){
//首先判断括号匹配
printf("中缀表达式:%s\n",infix_exp);
if(Match(S,infix_exp)){
printf("括号匹配正确\n");
}
else{
printf("括号匹配错误\n");
return;
}
char e;
while(*infix_exp != '\0'){
e = *infix_exp;
//只要是”(”一定压入栈
if(e == '('){
Push((int)e,&S);
}
//当是乘"*"或除"/" 先判断栈顶元素,如果是乘除,则先出栈再压入栈
else if((e == '*' || e== '/') ) {
if( IsEmpty(S) !=1 && ((char)Top(S) == '*' || (char)Top(S) == '/')){
*Suffix_exp = (char)Top(S);
Suffix_exp++;
Pop(&S);
Push((int)e,&S);
}else{
Push((int)e,&S);
}
}
//当是加"+"或减"-" 先判断栈顶元素,除了"(",一律先出栈再压入栈
else if(e == '+' || e== '-'){
if(IsEmpty(S) !=1 && (char)Top(S) != '('){
*Suffix_exp = (char)Top(S);
Suffix_exp++;
Pop(&S);
Push((int)e,&S);
} else{
Push((int)e,&S);
}
}
//括号里的运算符一律出栈
else if(e == ')'){
while((char)Top(S) != '('){
*Suffix_exp = (char)Top(S);
Suffix_exp++;
Pop(&S);
}
Pop(&S);
}
//数字直接放入数组
else{
*Suffix_exp = e;
Suffix_exp++;
}
infix_exp++;
}
//判断栈里是否还有运算符
while(IsEmpty(S) != 1){
*Suffix_exp = (char)Top(S);
Pop(&S);
Suffix_exp++;
}
*Suffix_exp = '\0';
}
5、简单的多项式运算
ElemTYpe Polynomial(SList S,char *infix_exp){
//将前缀表达式转成后缀表达式
int len = strlen(infix_exp);
char Suffix_exp[len];
InfixToSuffix(S,infix_exp,Suffix_exp);
char *exp = Suffix_exp;
printf("后缀表达式:%s\n",exp);
char e;
ElemTYpe tmp; //临时保存运算的值
while(*exp != '\0'){
e = *exp;
//数字统统入栈
if( e == '*' ){
tmp = Top(S);
Pop(&S);
tmp = Top(S)*tmp;
Pop(&S);
Push(tmp,&S);
}
else if( e == '/' ){
tmp = Top(S);
Pop(&S);
tmp = Top(S)/tmp;
Pop(&S);
Push(tmp,&S);
}
else if( e == '+' ){
tmp = Top(S);
Pop(&S);
tmp = Top(S)+tmp;
Pop(&S);
Push(tmp,&S);
}
else if( e == '-' ){
tmp = Top(S);
Pop(&S);
tmp = Top(S)-tmp;
Pop(&S);
Push(tmp,&S);
}else{
//atoi(&e) 字符数字转整型数字
Push(atoi(&e),&S);
}
exp++;
}
return tmp;
}
6、完整代码+运行截图
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int ElemTYpe;
//栈的数据结构
typedef struct SNode{
struct SNode* next;
ElemTYpe data;
}SNode,*SList;
//压栈
void Push(ElemTYpe e,SList *S);
//获取栈顶元素
ElemTYpe Top(SList S);
//出栈
void Pop(SList *S);
//判断栈空
int IsEmpty(SList S);
//打印
void PrintList(SList S);
//反转链表
void ReverseList(SList *LL,SList S);
//检查括号是否匹配 匹配1 不匹配0
int Match(SList S,char *exp);
//中缀表达式转后缀表达式
void InfixToSuffix(SList S,char *infix_exp,char *Suffix_exp);
//多项式运算
ElemTYpe Polynomial(SList S,char *infix_exp);
int main() {
//栈
SList S = NULL;
ElemTYpe e = 7;
//链表 不带头结点
SList LL = NULL;
for(int i = 6;i>0;i--){
e--;
Push(e,&LL);
}
printf("链表为:\n");
PrintList(LL);
ReverseList(&LL,S);
printf("反转后:\n");
PrintList(LL);
//多项式的运算
char infix_exp[] ={"3+1*(2+4*7)/5+6-8"};
e = Polynomial(S,infix_exp);
printf("%s 运算结果为 %d:\n",infix_exp,e);
return 0;
}
void Push(ElemTYpe e,SList *S){
SNode *tmp = (SNode *) malloc(sizeof(SNode));
tmp->data = e;
tmp->next = *S;
*S = tmp;
//printf("%d入栈\n",tmp->data);
}
ElemTYpe Top(SList S){
if(S == NULL){
printf("栈为空,无法获取栈顶元素\n");
return 0;
}
else{
return S->data;
}
}
int IsEmpty(SList S){
if(S == NULL)
return 1;
else
return 0;
}
void Pop(SList *S){
SNode *tmp;
tmp = *S;
if(tmp == NULL){
printf("无法出栈,栈为空\n");
return;
}
*S = (*S)->next;
//printf("%d出栈\n",tmp->data);
free(tmp);
}
void PrintList(SList S){
while (S != NULL){
printf("%d ",S->data);
S = S->next;
}
printf("\n");
}
/*
* 一般不建议像下面这样写,我是图省事,直接用之前的代码
* e = (ElemTYpe)tmp;
* tmp->next = (SNode *) Top(S);
* 最好在栈的数据结构中定义struct Node *类型的变量
*/
//反转链表
void ReverseList(SList *LL,SList S){
ElemTYpe e;
SNode *tmp = *LL;
//将链表的地址全部压入栈中
while (tmp != NULL){
e = (ElemTYpe)tmp;
Push(e,&S);
tmp = tmp->next;
}
//拿到链表的最后一个地址
tmp = (SNode *) Top(S);
*LL = tmp;
Pop(&S);
//依次拿到后续地址
while(IsEmpty(S) != 1){
tmp->next = (SNode *) Top(S);
Pop(&S);
tmp = tmp->next;
}
tmp->next = NULL;
}
//检查括号是否匹配 匹配1 不匹配0
int Match(SList S,char *exp) {
char e;
while (*exp != '\0') {
e = *exp;
switch (e) {
case '(':
case '[': {
Push((int) e, &S);
break;
}
case ')': {
if (IsEmpty(S) !=1 && (char) Top(S) == '('){
Pop(&S);
break;
}
else{
return 0;
}
}
case ']': {
if ( IsEmpty(S) !=1 &&(char) Top(S) == '[' ){
Pop(&S);
break;
}
else{
return 0;
}
}
}
exp++;
}
if (IsEmpty(S)) {
return 1;
}
else{
return 0;
}
}
//中缀表达式转后缀表达式
//优先级高的运算符一定是放在前面的
void InfixToSuffix(SList S,char *infix_exp,char *Suffix_exp){
//首先判断括号匹配
printf("\n中缀表达式:%s\n",infix_exp);
if(Match(S,infix_exp)){
printf("括号匹配正确\n");
}
else{
printf("括号匹配错误\n");
return;
}
char e;
while(*infix_exp != '\0'){
e = *infix_exp;
//只要是”(”一定压入栈
if(e == '('){
Push((int)e,&S);
}
//当是乘"*"或除"/" 先判断栈顶元素,如果是乘除,则先出栈再压入栈
else if((e == '*' || e== '/') ) {
if( IsEmpty(S) !=1 && ((char)Top(S) == '*' || (char)Top(S) == '/')){
*Suffix_exp = (char)Top(S);
Suffix_exp++;
Pop(&S);
Push((int)e,&S);
}else{
Push((int)e,&S);
}
}
//当是加"+"或减"-" 先判断栈顶元素,除了"(",一律先出栈再压入栈
else if(e == '+' || e== '-'){
if(IsEmpty(S) !=1 && (char)Top(S) != '('){
*Suffix_exp = (char)Top(S);
Suffix_exp++;
Pop(&S);
Push((int)e,&S);
} else{
Push((int)e,&S);
}
}
//括号里的一律出栈
else if(e == ')'){
while((char)Top(S) != '('){
*Suffix_exp = (char)Top(S);
Suffix_exp++;
Pop(&S);
}
Pop(&S);
}
//数字直接放入数组
else{
*Suffix_exp = e;
Suffix_exp++;
}
infix_exp++;
}
//判断栈里是否还有运算符
while(IsEmpty(S) != 1){
*Suffix_exp = (char)Top(S);
Pop(&S);
Suffix_exp++;
}
*Suffix_exp = '\0';
}
//简单的多项式运算
ElemTYpe Polynomial(SList S,char *infix_exp){
//将前缀表达式转成后缀表达式
int len = strlen(infix_exp);
char Suffix_exp[len];
InfixToSuffix(S,infix_exp,Suffix_exp);
char *exp = Suffix_exp;
printf("后缀表达式:%s\n",exp);
char e;
ElemTYpe tmp; //临时保存运算的值
while(*exp != '\0'){
e = *exp;
//数字统统入栈
if( e == '*' ){
tmp = Top(S);
Pop(&S);
tmp = Top(S)*tmp;
Pop(&S);
Push(tmp,&S);
}
else if( e == '/' ){
tmp = Top(S);
Pop(&S);
tmp = Top(S)/tmp;
Pop(&S);
Push(tmp,&S);
}
else if( e == '+' ){
tmp = Top(S);
Pop(&S);
tmp = Top(S)+tmp;
Pop(&S);
Push(tmp,&S);
}
else if( e == '-' ){
tmp = Top(S);
Pop(&S);
tmp = Top(S)-tmp;
Pop(&S);
Push(tmp,&S);
}else{
//atoi(&e) 字符数字转整型数字
Push(atoi(&e),&S);
}
exp++;
}
return tmp;
}
只是自己写着玩练手的,逻辑有些混乱,还有很多细节没考虑