关于用栈链表来实现中序表达式的一个小程序 《数据结构》

来源:互联网 发布:plc程序c语言 编辑:程序博客网 时间:2024/06/05 19:51

今天我在黄国瑜的《数据结构》一书中看到一段代码:于用栈链表来实现中序表达式,代码如下:

#include <stdio.h>#include <stdlib.h>#include <stdlib.h>struct s_node{int data;struct s_node *next;};typedef struct s_node s_list;typedef s_list *link;link operator=NULL;link operand=NULL;link push(link stack,int value){link newnode;newnode=(link)malloc(sizeof(s_list));if(!newnode){printf("\nMemory allocation failure!");return NULL;}newnode->data=value;newnode->next=stack;stack=newnode;return stack;}link pop(link stack,int *value){link top;if(stack!=NULL){top=stack;stack=stack->next;*value=top->data;free(top);return stack;}else*value=-1;}int empty(link stack){if(stack==NULL)return 1;elsereturn 0;}int is_operator(char operator){switch(operator){case '+': case '-': case '*': case '/': return 1;default:return 0;}}int priority(char operator){switch(operator){case '+':case '-':return 1;case '*':case '/':return 2;default: return 0;}}int two_result(int operator,int operand1,int operand2){switch(operator){case '+':return (operand2+operand1);case '-':return (operand2-operand1);case '*':return (operand2*operand1);case '/':return (operand2/operand1);}}void main(){char expression[50];int position=0;int op=0;int operand1=0;int operand2=0;int evaluate=0;printf("\nPlease input the inorder expression:");gets(expression);while(expression[position]!='\0'&&expression[position]!='\n'){if(is_operator(expression[position])){if(!empty(operator))while(priority(expression[position])<=priority(operator->data)&&!empty(operator)){operand=pop(operand,&operand1);operand=pop(operand,&operand2);operator=pop(operator,&op);operand=push(operand,two_result(op,operand1,operand2));}operator=push(operator,expression[position]);}elseoperand=push(operand,expression[position]-48);position++;}while(!empty(operator)){operator=pop(operator,&op);operand=pop(operand,&operand1);operand=pop(operand,&operand2);operand=push(operand,two_result(op,operand1,operand2));}operand=pop(operand,&evaluate);printf("The expression[%s]result is '%d'\n",expression,evaluate);}

执行时有一个警告:

查资料知在gcc编译器中没有gets函数,只有fgets,在这里为了结果的正确就不改了。这样也可以执行。

可是呢,在执行的时候,当你执行1+1,2*3,1+2*3,等等类似的表达式都是正确的,可是当执行1+1+1,2*3+1这样的时候就出现段错误,为什么呢?分析表达式,看出只要是前面的运算符小于后边的运算符时都是正确的,大于等于时都错了。

后来经过调试,发现第87行改为这样就对了:

之前:

while(priority(expression[position])<=priority(operator->data)&&!empty(operator))

改后:while(!empty(operator)&&priority(expression[position])<=priority(operator->data))

因为当输入运算符时要进行与上一次运算符的比较,如果这次的运算符优先级高于上一次的话,就执行下面的语句,执行完语句后,再次进行判断优先级,按照未改之前的看,当执行到priority(operator->data)时就出错了,因为i这时operator就是空了,它没有data了,所以出现了段错误。把empty(operator)提到前面来,进来后直接判断,为空直接执行while之外的语句,这样就对了。

(后记:虽然刚刚接触gdb,可是真好用,这次就是用它找到段错误的,要不是用它,不知道又得折腾到什么时候呢!)


原创粉丝点击