先序表示式恢復成二叉樹並計算--For初學者
阿新 • • 發佈:2018-12-18
思路是這樣的:首先,將先序表示式轉化成二叉樹,其次,用後序來遍歷二叉樹,最後,通過後序遍歷二叉樹的結果來計算最終結果。
那麼問題來了,為什麼我們要通過後序表示式來計算最終結果。這是因為後序表示式我們計算過,點選這裡,所以,我們先把後序表示式的程式碼放進.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; }
其實核心程式碼就那麼幾行(主要靠遞迴)。 執行結果: