[問題] 建立二元算式樹

看板C_and_CPP作者 (讀書人)時間15年前 (2010/06/05 22:38), 編輯推噓2(2011)
留言13則, 2人參與, 最新討論串1/1
遇到的問題: (題意請描述清楚) 讀入一個中序運算式 建立二元運算樹 並印出前中後序 我找到一個演算法 利用指標堆疊來做 如果要輸出一個運算元(數字)時 則建立一個新節點,儲存此運算元 其左右兩指標欄設定為NULL 並且將節點指標push置入指標堆疊sopd中 一個指標堆疊sopd儲存指標 然後運算子堆疊spor存+-*/ 如果要輸出一個運算子時 若此運算子之(優先權<=Sopr) 則由Sopr pop出運算子且建立新節點,儲存此運算子, 並且由指標堆疊sopd中pop彈出一個指標,存入新節點的右指標欄,再由sopd中彈出一個指標 ,存入新節點的左指標欄,然後將新節點指標再push置入sopd堆疊中。 否則直接將此運算子push到Sopr 假設我輸入1+2*3 應該建立 指標堆疊 sopd □□□□□□ 運算子堆疊sopr ↓ + □ 1 * □ 2 3 □←top 但是我的程式跑出來卻變成 sopd □□□□□□ 運算子堆疊sopr ↓↓↓ [ ] 1 2 3 [*]←top [+] 程式碼在下面(上色部分為演算法部分) 想破頭了不知怎麼改才對 煩請高人指點 開發平台: (例: VC++ or gcc/g++ or Dev-C++, Windows or Linux) VC6.0 有問題的code: (請善用置底文標色功能) #include <stdio.h> #include <stdlib.h> typedef struct Node { char data; struct Node* L; struct Node* R; }; Node* root; char stack[80]; //運算子堆疊 struct Node* nodeStack[80];//指標堆疊 int top=-1; int p=-1; char infix[80]; /*儲存中序運算式*/ void inOrder( Node* ROOT ) { if( ROOT != NULL ) { inOrder( ROOT->L ); printf( "%c\r\n", ROOT->data ); inOrder( ROOT->R ); } } void preOrder( Node* ROOT ) { if( ROOT != NULL ) { printf( "%c\r\n", ROOT->data ); preOrder( ROOT->L ); preOrder( ROOT->R ); } } void postOrder( Node* ROOT ) { if( ROOT != NULL ) { postOrder( ROOT->L ); postOrder( ROOT->R ); printf( "%c\r\n", ROOT->data ); } } void inserttree(Node left,Node right, Node father){ } int prio(char a){//優先權 switch(a){ case '+': return 1; case '-': return 1; case '*': return 2; case '/': return 2; default : return 0; } } void soprPush(char d) ////////////////////////////////////////// { top++; stack[top]=d; } /*刪除堆疊的頂端資料*/ char soprPop() ////////////////////////////////////////// { if(top == -1){ return 'z'; } else{ return(stack[top--]); //top--; } } void sopdPush(struct Node* N) { //假設 此stack的pointer 是 P p++; nodeStack[p] = N; } struct Node* sopdPop() { //假設 此stack的pointer 是 P if(p!=-1){ return nodeStack [p--]; } else return 0; } int main() { char *infix; infix=(char*)malloc( sizeof(char) ); // gets(infix); infix[0]='1'; infix[1]='+'; infix[2]='2'; infix[3]='*'; infix[4]='3'; struct Node* tmp; struct Node* oper; char token; int i=0, j=0; char test; while((token=infix[i++])!='\0'){ switch(token){ case '+': case '-': case '*': case '/': if(top!=-1){ test=soprPop();// 取出sopr頂端 暫不做pop 只是比較 top++; } else test=0; if(prio(token)<=prio(test)){ oper = (struct Node*)malloc( sizeof(struct Node) ); oper->data =soprPop(); oper->L = sopdPop(); oper->R = sopdPop(); sopdPush(oper); } else soprPush(token); break; default: tmp = (struct Node*)malloc( sizeof(struct Node) ); tmp->data = token; tmp->L = NULL; tmp->R = NULL; sopdPush(tmp); } } printf( "Print Tree by inorder\r\n" ); inOrder(nodeStack[0]); // 傳值呼叫 printf( "Print Tree by preOrder\r\n" ); preOrder( nodeStack[0] ); // 傳值呼叫 printf( "Print Tree by postOrder\r\n" ); postOrder( nodeStack[0] ); // 傳值呼叫 system( "PAUSE" ); return 0; } 補充說明: -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.136.250.5 ※ 編輯: king5014 來自: 114.136.250.5 (06/05 22:40) ※ 編輯: king5014 來自: 114.136.250.5 (06/05 22:41)

06/05 23:20, , 1F
你的堆疊內容看起來沒錯, 只差沒有把兩個運算元跟一個
06/05 23:20, 1F

06/05 23:21, , 2F
運算子接成一個子樹的動作
06/05 23:21, 2F

06/05 23:23, , 3F
但是程式碼卻有寫這一步...真奇怪 囧>
06/05 23:23, 3F

06/05 23:30, , 4F
在 if(top!=-1) 裡面, 為什麼要 top++ ?
06/05 23:30, 4F

06/06 00:32, , 5F
歐因為只是取頂端的直 所以要把top指回去(pop時會往下)
06/06 00:32, 5F

06/06 00:34, , 6F
等實際要pop的時候指標才不會錯
06/06 00:34, 6F

06/06 01:01, , 7F
我用別的方法寫好了 感謝
06/06 01:01, 7F

06/06 01:15, , 8F
把運算元接上去的時機應該是在讀到數字的時候, 且運算
06/06 01:15, 8F

06/06 01:16, , 9F
子堆疊中位在 top 的元素優先權 比 top-1 還大, 為了
06/06 01:16, 9F

06/06 01:17, , 10F
讓第一個進去的運算子不要直接輸出, 還需要動點手腳才
06/06 01:17, 10F

06/06 01:18, , 11F
行, 我有修改了一下, http://tinyurl.com/2d5ccwc
06/06 01:18, 11F

06/06 01:56, , 12F
注意運算元 pop 出來的順序跟在樹裡接的位置的關係
06/06 01:56, 12F

06/06 09:47, , 13F
感謝樓上(拜)
06/06 09:47, 13F
文章代碼(AID): #1C2c5tzB (C_and_CPP)