1. 程式人生 > >先序表示式恢復成二叉樹並計算--For初學者

先序表示式恢復成二叉樹並計算--For初學者

思路是這樣的:首先,將先序表示式轉化成二叉樹,其次,用後序來遍歷二叉樹,最後,通過後序遍歷二叉樹的結果來計算最終結果。 那麼問題來了,為什麼我們要通過後序表示式來計算最終結果。這是因為後序表示式我們計算過,點選這裡,所以,我們先把後序表示式的程式碼放進.h的檔案裡。 編輯環境:Code::Blocks,本人能力有限,難免有bug,大致思想是這樣的,其他功能讀者可以自行增加

//stcck.h
#ifndef STACK_H_INCLUDED
#define STACK_H_INCLUDED

#define MAX 100
typedef int ElemType;

typedef struct node {
  ElemType date;
 struct node *next;
} StackNode;
void InitStack(StackNode **p) {//棧的宣告
    (*p)=NULL;
}

int StackEmpty(StackNode *p) {//如果棧是空的返回0;不空返回1
    if(p==NULL)
        return 0;
    return 1;
}

void Push(StackNode **top, ElemType x) {//入棧操作
   StackNode *p;
   p=(StackNode *)malloc(sizeof(StackNode));
   p->date=x;
   p->next=*top;
   *top=p;
}

void Pop(StackNode **top, ElemType *x) {//出棧操作
    StackNode *p;
    if(*top==NULL)
        printf("Stack is empty!\n");
    else{
        *x=(*top)->date;
        p=*top;
        *top=(*top)->next;
        free(p);
    }

}
int Calc(char *s) {
    StackNode *p;
    InitStack(&p);
     ElemType x1,x2;
    int i=0,x;
    while(s[i])//進行四則運算
    {
        if(s[i]>='0'&&s[i]<='9')
            Push(&p,s[i]-48);
        else{
            Pop(&p,&x1);
            Pop(&p,&x2);
            if(s[i]=='+')
                Push(&p,x1+x2);
            if(s[i]=='-')
                Push(&p,x1-x2);
            if(s[i]=='*')
                Push(&p,x1*x2);
            if(s[i]=='/')
                Push(&p,x1/x2);
        }
        i++;
    }
    return p->date;
}

#endif // STACK_H_INCLUDED

這個程式碼跟https://blog.csdn.net/a_52hz/article/details/82858645的程式碼基本一樣,只不過今天主要的目的是回覆二叉樹,因此,把這個stack打包比較好。 好了,後序表示式的計算問題解決了,其實就是複製貼上上次的程式碼,先序表示式恢復成二叉樹,用的是遞迴的方法。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include"stack.h"
char str[MAX] ;
int i = 0;
typedef int DataType;
typedef struct treenode {
  DataType data;
  struct treenode * leftChild;
  struct treenode * rightChild;
}TreeNode;
void PrintBiTree(TreeNode *bt, int n) {
  int i;
  if (bt == NULL) return;
  PrintBiTree(bt->rightChild, n+1);
  for (i = 0; i < n-1; i++) printf("   ");
  if (n > 0) {
    printf("---");
    printf("%c\n", bt->data);
  }
  PrintBiTree(bt->leftChild, n+1);
}
void PrintF(TreeNode *p)//前序遍歷
{
    if(p!=NULL)
    {
        printf("%c",p->data);
        PrintF(p->leftChild);
        PrintF(p->rightChild);
    }
}
void PrintM(TreeNode *p)//中序遍歷
{
    if(p!=NULL)
    {
        PrintM(p->leftChild);
        printf("%c",p->data);
        PrintM(p->rightChild);
    }
}
void PrintP(TreeNode *p)//後序遍歷
{
    if(p!=NULL)
    {
        PrintP(p->leftChild);
        PrintP(p->rightChild);
        printf("%c",p->data);
        str[i++] = p->data;//為後序計算準備
    }
}
void RecoveryTree(TreeNode **p)//回覆成二叉樹
{
    char ch;
    scanf("%c",&ch);
    if(ch!='$')
    {
        *p = (TreeNode *)malloc(sizeof(TreeNode));//申請新的結點
        (*p)->data = ch;
        RecoveryTree(&(*p)->leftChild);//一直左插,直到遇到$
        RecoveryTree(&(*p)->rightChild);//一直右插,直到遇到$
    }
    else *p = NULL;//$的位置置成NULL
}
int main() {
    TreeNode *p;
    RecoveryTree(&p);
    printf("The tree is:\n");
    PrintBiTree(p,1);
    printf("\n\nThe forward expression is:    ");
    PrintF(p);
    printf("\n\nThe middle expression is:    ");
    PrintM(p);
    printf("\n\nThe following expression is:    ");
    PrintP(p);
    printf("\n\nThe result is:  %d", Calc(str));
    return 0;
}

其實核心程式碼就那麼幾行(主要靠遞迴)。 執行結果: 在這裡插入圖片描述