[C语言]链栈以及后缀表达式

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>
typedef int Type; //自定义类型 

typedef struct _Stack
{
    Type data;//保存值 
    struct _Stack *next;//指向下一个 
		
}Stack,*StackPtr;
/*这里一个Stack里有一个值和一个指向下一个Stack的指针,StackPtr为一个指向一个Stack的指针*/
typedef struct
{
	StackPtr top;//用于保存Stack的头
	int cnt;//记录位数 
}Top,*TopPtr;
/*这里一个Top里有一个指向一个链栈头的指针和一个计数变量,TopPtr为一个指向一个Top的指针*/
TopPtr Stack_Creat()//创建一个Stack并返回指向它的头的指针
{
	TopPtr p = (TopPtr)malloc(sizeof(Top));
	if(!p)
	{
		return NULL;
	}
	p->top = NULL;
	p->cnt = 0;
	return p;
}
int Stack_Add(TopPtr S,Type data)//增加数字
{
	StackPtr p = (StackPtr)malloc(sizeof(Stack));
	if(!p)
	{
		return 0;
	}
	p->data = data;
	p->next = S->top;
	S->top = p;
	S->cnt++;
	return 1;
}
int Stack_Empty(TopPtr S)//判空
{
	if(S->top)
	{
		return 0;
	}else
	{
		return 1;
	}
}
int Stack_Pop(TopPtr S)//弹出 
{
	if(!Stack_Empty(S))
	{
		StackPtr p = S->top;
		Type data = p->data;
		S->top = S->top->next;
		S->cnt--;
		free(p);
		return 1;
	}else
	{
		return 0;
	}
}
int Stack_Print(TopPtr S)//展示 
{
	if(Stack_Empty(S))
	{
		return 0;
	}
	StackPtr p = S->top;
	while(p)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	putchar('\n');
	return 1;
}
int Stack_Free(TopPtr S)//释放 
{
	if(!S)
	{
		return 0;
	}
	while(S->top)
	{
		StackPtr p = S->top;
		S->top = S->top->next;
		free(p);
	}
	return 1;
}
int Stack_Count(TopPtr S)//返回链栈有多少个空间.....
{
	return S->cnt;
}
int Stack_Clear(TopPtr S)//清空链栈
{
	while(Stack_Pop(S));
	return 1;
}
int main()
{
	TopPtr S = Stack_Creat();
	while(1)
	{
	    system("cls");
	    fflush(stdin);
	    printf(
		"1.加入数字\n"
		"2.弹出数字\n"
		"3.判空\n"
		"4.展示\n"
		"5.已存储的数字个数\n"
		"6.清空栈\n"
		"7.退出\n"
		);
		int num;
		if(scanf("%d",&num)==1&&num>=1&&num<=7)
		{
			if(num == 7)
			{
				Stack_Free(S);
				break;
			}
			if(num == 1)
			{
				int flag = 1;
				Type data;
				printf("输入q停止\n");
				while(scanf("%d",&data)==1)
				{
					if(!Stack_Add(S,data))
				    {
				    	flag = 0;
					    printf("ERROR\n");
				    }
				}
				if(flag)
				{
					printf("OK\n");
				}
				getch();
			}else if(num == 2)
			{
				if(Stack_Pop(S))
				{
					printf("OK\n");
				}else
				{
					printf("ERROR\n");
				}
				getch();
			}else if(num == 3)
			{
				if(Stack_Empty(S))
				{
					printf("Empty\n");
				}else
				{
					printf("No Empty\n");
				}
				getch();
			}else if(num == 4) 
			{
				if(!Stack_Print(S))
				{
					printf("Empty\n");
				}
				getch();
			}else if(num == 5)
			{
				printf("%d\n",Stack_Count(S));
				getch();
			}else
			{
				if(Stack_Clear(S))
				{
					printf("OK\n");
				}
				getch();
			}
		}
	}
	return 0;
} 

后缀表达式:
(从某位大佬那发现的,很容易理解)
在这里插入图片描述

//感谢大佬的文章
https://blog.csdn.net/u012507347/article/details/52245233

实现后缀表达式的运算

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct _Stack  //创建栈空间 
{
    int data;
    struct _Stack *next;
}Stack,*StackPtr;
typedef struct _Point  //创建指向栈顶的指针空间 
{
    StackPtr top;
}Point,*PointPtr;
PointPtr Point_Creat()//创造链栈
{
    PointPtr p = (PointPtr)malloc(sizeof(Point));
    p->top = NULL;
    return p;
}
void Stack_Add(PointPtr p,int num)//入栈
{
    StackPtr q = (StackPtr)malloc(sizeof(Stack));
    q->data = num;;
    q->next = p->top;
    p->top = q;
}
int Stack_Pop(PointPtr p)//出栈
{
    StackPtr q = p->top;
    int num = q->data;
    p->top = p->top->next;
    free(q);
    return num;
}
int IsNum(char c)//判断是否是数字
{
    if(c >= '0' && c <= '9')
    {
        return 1;
    }else
    {
        return 0;
    }
}
void Operator(char c,PointPtr Top)//遇到符号的操作
{
    int left,right;
    right = Stack_Pop(Top);//左操作数
    left = Stack_Pop(Top);//右操作数
    /*匹配相关运算符进行运算*/
    if(c == '+')
    {
        Stack_Add(Top,left+right);
    }else if(c == '-')
    {
        Stack_Add(Top,left-right);
    }else if(c == '*')
    {
        Stack_Add(Top,left*right);
    }else
    {
        Stack_Add(Top,left/right);
    }
}
void Control(char c,PointPtr Top)//判断符号还是数字
{
    if(IsNum(c))//如果是数字就入栈
    {
        Stack_Add(Top,c-'0');
    }else//是符号就符号操作
    {
        Operator(c,Top);
    }
}
int evalRPN(char (*tokens)[10], int tokensSize){//传入后缀表达式
    PointPtr Top = Point_Creat();//创建链栈
    for(int i = 0;i<tokensSize;i++)
    {
        int len = strlen(tokens[i]);//计算长度
        if(len == 1)//如果长度是1就判断是符号还是数字
        {
            Control(tokens[i][0],Top);
        }else//长度大于1
        {
            int num = 0,flag = 0;
            for(int j = 0;j<len;j++)
            {
                if(j == 0 && tokens[i][0] == '-')//如果是负数就标记下
                {
                    flag = 1;
                }else//将字符串转换为数字
                {
                    num  = (num*10+(tokens[i][j]-'0'));
                }
            }
            if(flag)//如果是负数就取负值
            {
                num = num * -1;
            }
            Stack_Add(Top,num);//把数字入栈
        }  
    }
    return Top->top->data;//返回计算的结果(就是链栈最后一个值)
}
int main()
{
	char tokens[20][10] = {"10","6","9","3","+","-11","*","/","*","17","+","5","+"};
	printf("%d",evalRPN(tokens,13));
	return 0;
}

根据力扣 150. 逆波兰表达式求值 进行编写,over

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值