数据结构实验3
题目:设计一个算法,将一般算术表达式转化为逆波兰表达式,并求逆波兰表达 式的值。
test.h
#include<stdio.h> #include<stdlib.h> #include<string.h> #define MAXSIZE 20 typedef char DataType; typedef struct node { DataType data; struct node *next; }LStackNode,*LinkStack; void InitStack(LinkStack *top) /*将链栈初始化为空*/ { if((*top=(LinkStack)malloc(sizeof(LStackNode)))==NULL) /*为头结点分配一个存储空间*/ exit(-1); (*top)->next=NULL; /*将链栈的头结点指针域置为空*/ } int StackEmpty(LinkStack top) /*判断链栈是否为空,就是通过判断头结点的指针域是否为空*/ { if(top->next==NULL) /*当链栈为空时*/ return 1; /*返回1*/ else /*否则*/ return 0; /*返回0*/ } int PushStack(LinkStack top, DataType e) /*进栈操作就是要在链表的第一个结点前插入一个新结点,进栈成功返回1*/ { LStackNode *p; /*定义指向第i个元素的前驱结点指针pre,指针p指向新生成的结点*/ if((p=(LStackNode*)malloc(sizeof(LStackNode)))==NULL) { printf("内存分配失败!"); exit(-1); } p->data=e; /*指针p指向头结点*/ p->next=top->next; top->next=p; return 1; } int PopStack(LinkStack top,DataType *e) /*删除单链表中的第i个位置的结点。删除成功返回1,失败返回0*/ { LStackNode *p; p=top->next; if(!p) /*判断链栈是否为空*/ { printf("栈已空"); return 0; } top->next=p->next; /*将栈顶结点与链表断开,即出栈*/ *e=p->data; /*将出栈元素赋值给e*/ free(p); /*释放p指向的结点*/ return 1; } int GetTop(LinkStack top,DataType *e) /*取栈顶元素。取栈顶元素成功返回1,否则返回0*/ { LStackNode *p; p=top->next; /*指针p指向栈顶结点*/ if(!p) { printf("栈已空"); return 0; } *e=p->data; /*将p指向的结点元素赋值给e*/ return 1; } int StackLength(LinkStack top) /*求表长操作。依次从栈顶指针开始,通过结点的指针域访问每一个结点,并计数,返回表的长度值*/ { LStackNode *p; int count=0; /*定义一个计数器,并初始化为0*/ p=top; /*p指向栈顶指针*/ while(p->next!=NULL) /*如果栈中还有结点*/ { p=p->next; /*依次访问栈中的结点*/ count++; /*每次找到一个结点,计数器累加1*/ } return count; /*返回栈的长度*/ } void DestroyStack(LinkStack top) /*销毁链栈*/ { LStackNode *p,*q; p=top; while(!p) /*如果栈还有结点*/ { q=p; /*q就是要释放的结点*/ p=p->next; /*p指向下一个结点,即下一次要释放的结点*/ free(q); /*释放q指向的结点空间*/ } } void ClearStack(LinkStack top) /*销毁链栈*/ { LStackNode *p,*q; p=top->next; while(!p) /*如果栈还有结点*/ { q=p; /*q就是要释放的结点*/ p=p->next; /*p指向下一个结点,即下一次要释放的结点*/ free(q); /*释放q指向的结点空间*/ } } /*操作数栈定义*/ typedef struct { float data[MAXSIZE]; int top; }OpStack; /*函数声明*/ void TranslateExpress(char s1[],char s2[]); float ComputeExpress(char s[]); /*计算后缀表达式的值*/ float ComputeExpress(char a[]) { OpStack S; /*定义一个操作数栈*/ int i=0,value; float x1,x2; float result; S.top=-1; /*初始化栈*/ while(a[i]!='\0') /*依次扫描后缀表达式中的每个字符*/ { if(a[i]!=' '&&a[i]>='0'&&a[i]<='9') /*如果当前字符是数字字符*/ { value=0; while(a[i]!=' ') /*如果不是空格,说明数字字符是两位数以上的数字字符*/ { value=10*value+a[i]-'0'; i++; } S.top++; S.data[S.top]=value; /*处理之后将数字进栈*/ } else /*如果当前字符是运算符*/ { switch(a[i]) /*将栈中的数字出栈两次,然后用当前的运算符进行运算,再将结果入栈*/ { case '+': x1=S.data[S.top]; S.top--; x2=S.data[S.top]; S.top--; result=x1+x2; S.top++; S.data[S.top]=result; break; case '-': x1=S.data[S.top]; S.top--; x2=S.data[S.top]; S.top--; result=x2-x1; S.top++; S.data[S.top]=result; break; case '*': x1=S.data[S.top]; S.top--; x2=S.data[S.top]; S.top--; result=x1*x2; S.top++; S.data[S.top]=result; break; case '/': x1=S.data[S.top]; S.top--; x2=S.data[S.top]; S.top--; result=x2/x1; S.top++; S.data[S.top]=result; break; } i++; } } if(!S.top!=-1) /*如果栈不空,将结果出栈,并返回*/ { result=S.data[S.top]; S.top--; if(S.top==-1) return result; else { printf("表达式错误"); exit(-1); } } } void TranslateExpress(char str[],char exp[]) /*将输入的中缀表达式转换为后缀表达式*/ { LinkStack S; /*定义一个栈,用于存放运算符*/ char ch; DataType e; int i=0,j=0; InitStack(&S); ch=str[i]; i++; while(ch!='\0') /*依次扫描中缀表达式中的每个字符*/ { switch(ch) { case'(': /*如果当前字符是左括号,则将其进栈*/ PushStack(S,ch); break; case')': /*如果是右括号,将栈中的运算符出栈,并将其存入数组exp中*/ while(GetTop(S,&e)&&e!='(') { PopStack(S,&e); exp[j]=e; j++; exp[j]=' '; /*加上空格*/ j++; } PopStack(S,&e); /*将左括号出栈*/ break; case'+': case'-': /*如果遇到的是'+'和'-',因为其优先级低于栈顶运算符的优先级,所以先将栈顶字符出栈,并将其存入数组exp中,然后将当前运算符进栈*/ while(!StackEmpty(S)&&GetTop(S,&e)&&e!='(') { PopStack(S,&e); exp[j]=e; j++; exp[j]=' '; /*加上空格*/ j++; } PushStack(S,ch); /*当前运算符进栈*/ break; case'*': /*如果遇到的是'*'和'/',先将同级运算符出栈,并存入数组exp中,然后将当前的运算符进栈*/ case'/': while(!StackEmpty(S)&&GetTop(S,&e)&&e=='/'||e=='*') { PopStack(S,&e); exp[j]=e; j++; exp[j]=' '; /*加上空格*/ j++; } PushStack(S,ch); /*当前运算符进栈*/ break; case' ': /*如果遇到空格,忽略*/ break; default: /*如果遇到的是操作数,则将操作数直接送入数组exp中,并在其后添加一个空格,用来分隔数字字符*/ while(ch>='0'&&ch<='9') { exp[j]=ch; j++; ch=str[i]; i++; } i--; exp[j]=' '; j++; } ch=str[i]; /*读入下一个字符,准备处理*/ i++; } while(!StackEmpty(S)) /*将栈中所有剩余的运算符出栈,送入数组exp中*/ { PopStack(S,&e); exp[j]=e; j++; exp[j]=' '; /*加上空格*/ j++; } exp[j]='\0'; }
test.c
typedef int elemtype; #include"test.h" void singleToDubleCireList(List first) { List p,q; p=first; q=p->next; while(q!=first) { q->prior=p; p=q; q=q->next; } q->prior=p; } int main() { List L=Init_List(); int a[10]={4,4,5,5,6,6,7,7,8,8},i; for(i=9;i>=0;i--) INSERTBEFORE(L,a[i]); printf("测试数据:\n"); Print_List(L); printf("\n"); printf("改变后,采用反向遍历:\n"); singleToDubleCireList(L); Print_ListR(L); printf("\n"); }