数据结构 中缀转后缀 后缀转二叉树并打印 后缀计算值

主函数

/  main.cpp

//  数据结构第二次上机

//

//  Created by tao on 2017/3/30.

//  Copyright © 2017 tao. All rights reserved.

//


#include <iostream>

#include "LinStack.h"

#include <mm_malloc.h>

#include <ctype.h>

#include <stdlib.h>

#include "BiTree.h"

#include <stack>

#include <queue>

using namespace std;

typedef double DataType;


//判断是否为符号

int isoperator(char op)

{

    switch(op)

    {

    case '+':

    case '-':

    case '*':

    case '/':

            return 1;

    default :

            return 0;

    }

}


//判断运算符号优先级

int priority(char op)

{

    if(op == '+'||op == '-')

        return 1;

    if(op == '*'||op == '/')

        return 2;

    if(op == '(')

        return 0;

    if (op == '#')

        return -1;

    return 0;

}


//把中缀表达式转换为后缀表达式

//strPost[]数组存放后缀表达式,strInfix[]存放中缀表达式

void postfix(char strPost[],char strInfix[])

{

    

    DataType x=0;

    int i=0,j=0;

    LSNode *head;

    StackInitiate(&head);

    StackPush(head, '#');//初始化后将栈顶元素置为#

    for(i = 0;strInfix[i] != '#';i++)

    {

        if((strInfix[i]>='0' && strInfix[i] <='9')||strInfix[i] =='.')

    //如果这个是数字的话,就直接把中缀中这个元素写到后缀里

        {

                strPost[j++] = strInfix[i];

               // strPost[j++] = ' ';

            

        }

        else

        {

            //strPost[j++] = ' ';

            

            if(strInfix[i] == '(')//如果(,不用比较直接入栈

            {

                StackPush(head, strInfix[i]);

                StackTop(head, &x);

               // i++;

            }

                

            else if(strInfix[i] == ')')//如果是),不断退栈,直到找到与之对应的(

            {

                StackTop(head, &x);

                while(x != '(')

                {

                     strPost[j++] = ' ';

                    StackPop(head, &x);

                    //x弹出之后写到这个后缀表达式中

                    strPost[j++]=x;

                    StackTop(head, &x);

                    //strPost[i++]=x;

                }

                StackPop(head, &x);//将与右括号对应的左括号退栈

                StackTop(head, &x);

               // strPost[j++]=strInfix[i];

            }

            //如果是除了左括号和右括号的操作符

            else if(isoperator(strInfix[i]))

            {

                //先输入一个空格隔开操作数

                strPost[j++] = ' ';

                x = StackTop(head, &x);

                while(priority(strInfix[i])<=priority(x))

                // 当前的操作符小于等于栈顶操作符的优先级时,将栈顶操作符写入到后缀表达式,重复此过程

                {

                    StackPop(head, &x);

                    // strPost[j++] = ' ';

                    strPost[j++]=x;

                    

                    if(x==StackTop(head, &x))

                        StackPop(head, &x);

                   // strPost[j++]=x;

                    strPost[j++] = ' ';

                    StackTop(head, &x);

                }

                StackPush(head, strInfix[i]);// 当前操作符优先级大于栈顶操作符的优先级,将该操作符入栈

                StackTop(head, &x);

            }

        }

        

        }

    

    x = StackTop(head, &x);

    //一般这个时候栈里还有元素 直接弹出到后缀表达式

    while (x!='#')

    {

        strPost[j++] = ' ';

        strPost[j++]=StackPop(head, &x);

        

    }

    

    }


//读入数据函数

//把数字字符串转换成相应的数字

double numRead(char str[],int *i)

{

    double x=0.0;

    int k = 0;

    while(str[*i] >='0' && str[*i]<='9'// 处理整数部分

    {

        x = x*10+(str[*i]-'0');

        

        (*i)++;

    }

    

    if(str[*i]=='.') // 处理小数部分

    {

        (*i)++;

        while(str[*i] >= '0'&&str[*i] <='9')

        {

            x = x * 10 + (str[*i]-'0');

            (*i)++;

            k++;//k来记录一共几个小数

        }

    }

    while(k!=0)

    {

        x /= 10.0;//如果k=3,那就有3位小数,除以3次十

        k--;

    }

    

    return x;

}





//后缀表达式转换成表达式树

void treeCreate(char poststr[])

{

    stack<BiTreeNode*>s;//定义一个存放节点指针的栈

   // stack<double>s1;//定义一个存放数字的栈

    BiTreeNode *p = nullptr,*a,*b;

    double x=0.0;


  

    int i;

    for(i = 0;poststr[i] != '#';i++)

   {

       Initiate(&p);

       if((poststr[i]>='0' && poststr[i] <='9')||poststr[i] =='.')

       {

           //是数字的话,就把这个节点的数值存入,左孩子和右孩子都设成null,然后,压入存节点的栈

           x = numRead(poststr, &i);

           p->data = x;

           p->leftChild = NULL;

           p->rightChild = NULL;

           s.push(p);//指针p进栈

          // s.push(numRead(poststr,&i));

       }

      else if(isoperator(poststr[i]))

        {

      //新建节点p,分别表示她的左孩子和右孩子

            

        Initiate(&a);

        Initiate(&b);

        

        a = s.top();

        s.pop();

        

        b = s.top();

        s.pop();

       

        p->data = poststr[i];

        p->rightChild = a;

        p->leftChild = b;

        s.push(p);

    }

    else

        continue;

   }

    //弹出节点

    BiTreeNode *root = s.top();

    s.pop();

    PrintBiTree(root, 1);

    

    }



//由后缀计算值

double post_calculate(char poststr[])

{

    LSNode *head;

    StackInitiate(&head);

    int i=0;

    DataType x = 0,x1 = 0,x2 = 0;

    double a;

    

    

    while (poststr[i] != '#')

    {

       

        if((poststr[i]>='0' && poststr[i] <='9')||poststr[i] =='.')

        {

            x = numRead(poststr, &i);

            StackPush(head,x);

        }

        else if(poststr[i] == ' ')

            i++;

        else if(poststr[i] == '+')

        {

            StackPop(head, &x1);

            StackPop(head, &x2);

            StackPush(head, x1+x2);

            StackTop(head, &x);

            i++;

        }

        else if(poststr[i] == '-')

        {

            StackPop(head, &x1);

            StackPop(head, &x2);

            StackPush(head, x2-x1);

            StackTop(head, &x);

            i++;

        }

        else if(poststr[i] == '*')

        {

            StackPop(head, &x1);

            StackPop(head, &x2);

            StackPush(head, x1*x2);

            StackTop(head, &x);

            i++;

        }

        else if(poststr[i] == '/')

        {

            StackPop(head, &x1);

            StackPop(head, &x2);

            StackPush(head, x2/x1);

            StackTop(head, &x);

            i++;

        }

    }

    a = StackTop(head, &x);

    cout<<a<<endl;

    return a;


}



int main(int argc, const char * argv[])

{

   // int i;

    //char str[512];// =" 3 4 + 5 * 6 - #";

    //cout<<"后缀表达式是:"<<endl;

    char str[512];

    char post[512];

    int ok = 1;

    while(ok == 1)

    {

        printf("输入你想转换的中缀表达式哟,记得以井号键结束ヾ(=·ω·=)o\n");

        

        scanf("%s",str);

        postfix(post,str);

        cout<<"这是转化后的后缀表达式(づ ̄3 ̄)づ"<<endl;

           cout<<post<<endl;

        cout<<"~送你二叉树(•̀•́)و\n"<<endl;

        treeCreate(post);

        cout<<"这是计算出来的值(づ。◕‿‿◕。)"<<endl;

        post_calculate(post);

        printf("你还想继续吗?'1'继续,'2'返回哦(·ェ·。)\n");

        scanf("%d",&ok);

        if (ok == 0)

        {

            cout<<"好了,这一切都结束了(_)"<<endl;

            

            return 0;

        }


    }


二叉树头文件

//

//  BiTree.h

//  数据结构第二次上机

//

//  Created by tao on 2017/4/3.

//  Copyright © 2017 tao. All rights reserved.

//


#ifndef BiTree_h

#define BiTree_h



#endif /* BiTree_h */

typedef double DataType;

typedef struct Node

{

    double data;

    struct Node *leftChild;

    struct Node *rightChild;

}BiTreeNode;



BiTreeNode* Initiate(BiTreeNode **root)

{

    *root = (BiTreeNode *)malloc(sizeof(BiTreeNode));

    (*root) -> leftChild = NULL;

    (*root) -> rightChild = NULL;

    return *root;

}



BiTreeNode *InsertLeftNode(BiTreeNode *curr,BiTreeNode *p)

{

    DataType x;

    BiTreeNode *s,*t;

    if(curr == NULL) return NULL;

    t = curr -> leftChild;

    s = (BiTreeNode *)malloc(sizeof(BiTreeNode));

    s -> data = x;

    s -> leftChild = t;

    s -> rightChild = NULL;

    curr -> leftChild = s;

    return curr->leftChild;

}


BiTreeNode *InsertRightNode(BiTreeNode *curr,BiTreeNode *p)

{

    DataType x;

    BiTreeNode *s,*t;

    if(curr == NULL) return NULL;

    t = curr -> rightChild;

    s = (BiTreeNode *)malloc(sizeof(BiTreeNode));

    s -> data = x;

    s -> rightChild = t;

    s -> leftChild = NULL;

    curr -> rightChild = s;

    return curr->rightChild;

}


void Destroy(BiTreeNode **root)

{

    if((*root)!=NULL&&(*root)->leftChild!=NULL)

        Destroy(&(*root)->leftChild);

    if((*root)!=NULL&&(*root)->rightChild!=NULL)

        Destroy(&(*root)->rightChild);

    free(*root);

}


BiTreeNode *DeleteLeftTree(BiTreeNode *curr)

{

    if(curr == NULL||curr->leftChild == NULL) return NULL;

    Destroy(&curr -> leftChild);

    curr->leftChild = NULL;

    return curr;

}


BiTreeNode *DeleteRightTree(BiTreeNode *curr)

{

    if(curr == NULL||curr->rightChild == NULL) return NULL;

    Destroy(&curr -> rightChild);

    curr->rightChild = NULL;

    return curr;

}


void PreOrder(BiTreeNode *root,void visit(DataType item))

{

    if(root != NULL)

    {

        visit(root->data);

        PreOrder(root->leftChild,visit);

        PreOrder(root->rightChild,visit);

    }

}


void InOrder(BiTreeNode *root,void visit(DataType item))

{

    if(root != NULL)

    {

        InOrder(root->leftChild,visit);

        visit(root->data);

        InOrder(root->rightChild,visit);

    }

}


void PostOrder(BiTreeNode *root,void visit(DataType item))

{

    if(root != NULL)

    {

        PostOrder(root->leftChild,visit);

        PostOrder(root->rightChild,visit);

        visit(root->data);

    }

}


void PrintBiTree(BiTreeNode *root,int n)

{

    int i;

    char a;

    if(root == NULL) return;

    PrintBiTree(root->rightChild, n+1);

    for(i = 0;i<n-1;i++)

        printf("    ");

    if (n>0)

    {

        printf("--- ");

        if(root ->rightChild ==NULL && root ->leftChild ==NULL)

            printf("%f\n",root->data);

        else

        {

            a = (char)(root->data);

            printf("%c\n",a);

        }

    

    }

    PrintBiTree(root->leftChild,n+1);

}




 }



链式栈头文件

//

//  LinStack.h

//  数据结构第二次上机

//

//  Created by 胡雨涛 on 2017/3/30.

//  Copyright © 2017 胡雨涛. All rights reserved.

//


typedef double DataType;



typedef struct snode

{

    DataType data;

    struct snode *next;

}LSNode;



void StackInitiate(LSNode **head)

{

    *head = (LSNode *)malloc(sizeof(LSNode));

    (*head)->next = NULL;

}


int StackNotEmpty(LSNode *head)

{

    if(head -> next == NULL) return 0;

    else return 1;

}

/*

void StackPush(LSNode *head,DataType x)

{

    LSNode *p;

    p = (LSNode *)malloc(sizeof(LSNode));

    p->data = x;

    p->next = head->next;

    head->next = p;

}

*/


void StackPush(LSNode *head,DataType x)

{

    LSNode *p;

    p = (LSNode *)malloc(sizeof(LSNode));

    p->data = x;

    p->next = head->next;

    head->next = p;

}




int StackPop(LSNode *head,DataType *d)

{

    LSNode *p = head->next;

    if(p==NULL)

    {

        printf("堆栈已空出错!");

        return 0;

    }

    head->next = p->next;

    *d = p->data;

    free(p);

    return *d;

}

int StackTop(LSNode *head,DataType *d)

{

    LSNode *p = head->next;

    if(p == NULL)

    {

        printf("堆栈已空出错!");

        return 0;

    }

    *d = p->data;

    return *d;

}



void Destroy(LSNode *head)

{

    LSNode *p,*p1;

    p = head;

    while (p!=NULL)

    {

        p1=p;

        p=p->next;

        free(p1);

    }

}







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值