数据结构实验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");
}

 

posted @ 2017-06-01 20:12  五邑bb  阅读(1729)  评论(0编辑  收藏  举报