二叉樹後序遍歷的迭代實現
阿新 • • 發佈:2019-02-01
#include <stdio.h> #include <stdlib.h> struct BinTreeNode{ int Element; int visited;//用於標記當前節點有沒有被訪問過 struct BinTreeNode* Left; struct BinTreeNode* Right; }; //以下程式碼用於建樹,便於測試中序遍歷程式是否正確 struct BinTreeNode* CreateNode(int data){//創造新節點 struct BinTreeNode* temp; temp=(struct BinTreeNode*)malloc(sizeof(struct BinTreeNode)); if(temp!=NULL){ temp->Element=data; temp->visited=0; temp->Left=NULL; temp->Right=NULL; } return temp; } struct BinTreeNode* FindNode(struct BinTreeNode* BinTree,int data)//查詢 { if(BinTree==NULL) return NULL; if(BinTree->Element==data) return BinTree; struct BinTreeNode* temp=NULL; if(BinTree->Left!=NULL) temp=FindNode(BinTree->Left,data); if(temp==NULL&&BinTree->Right!=NULL) temp=FindNode(BinTree->Right,data); return temp; } //假設每個節點值不同 #define LEFT 1 #define RIGHT 0 struct BinTreeNode* InsertNode(struct BinTreeNode* BinTree,int loc,int dir,int data)//插入節點,loc代表插入的數的父節點的值,dir表示方向 { struct BinTreeNode* parent=FindNode(BinTree,loc); if(parent!=NULL){ struct BinTreeNode* temp=CreateNode(data); if(dir==LEFT) parent->Left=temp; else parent->Right=temp; } return BinTree; } //二叉樹前序遍歷的迭代實現,用到棧 /* 思路: 後序不同於前序和中序,後序要訪問完左子樹和右子樹才能訪問節點; 因此遍歷到一個節點,訪不訪問他取決於它的左右子樹是不是均被訪問過了; 需要在結構體中加入一個用來判斷的變數visited,如果其左右子樹均被訪問過,就賦值為1 過程: 當前節點,沿它的左路徑,開始遍歷,直到路徑末尾,開始回溯 回溯過程中的節點的左兒子一定被訪問過了或者不存在,如果其右兒子不存在或者右兒子已經被訪問過,訪問當前節點 如果其右兒子存在,此時以其右兒子為基礎,再去遍歷其左路徑 */ void PostOrderTrversal(struct BinTreeNode* BinTree) { //建棧 struct BinTreeNode* stack[100]; int top=-1; int flag;//判斷要不要去遍歷一個新的 (子)樹左路徑 struct BinTreeNode* Temp=BinTree; while(Temp!=NULL||top>=0){ flag=1; while(Temp!=NULL){//遍歷 (子)樹左路徑 Temp->visited=1; top++; stack[top]=Temp; Temp=Temp->Left; } while(flag&&top>=0){ if(stack[top]->Right==NULL||stack[top]->Right->visited==1){//右兒子不存在或者右兒子已經被訪問過 printf("%d ",stack[top]->Element); top--; } else{ Temp=stack[top]->Right; flag=0;//flag為0,遍歷一個新的 (子)樹左路徑 } } } return; } int main() { struct BinTreeNode* BinTree; //先手工建立一個樹 //不提倡此類建樹方法,只是暫時用於測試程式 BinTree=CreateNode(10); BinTree=InsertNode(BinTree,10,1,20); BinTree=InsertNode(BinTree,10,0,30); BinTree=InsertNode(BinTree,30,1,40); BinTree=InsertNode(BinTree,40,0,50); //遍歷 PostOrderTrversal(BinTree); return 0; }
//不用flag也可以
#include <stdio.h> #include <stdlib.h> struct BinTreeNode{ int Element; int visited;//用於標記當前節點有沒有被訪問過 struct BinTreeNode* Left; struct BinTreeNode* Right; }; //以下程式碼用於建樹,便於測試中序遍歷程式是否正確 struct BinTreeNode* CreateNode(int data){//創造新節點 struct BinTreeNode* temp; temp=(struct BinTreeNode*)malloc(sizeof(struct BinTreeNode)); if(temp!=NULL){ temp->Element=data; temp->visited=0; temp->Left=NULL; temp->Right=NULL; } return temp; } struct BinTreeNode* FindNode(struct BinTreeNode* BinTree,int data)//查詢 { if(BinTree==NULL) return NULL; if(BinTree->Element==data) return BinTree; struct BinTreeNode* temp=NULL; if(BinTree->Left!=NULL) temp=FindNode(BinTree->Left,data); if(temp==NULL&&BinTree->Right!=NULL) temp=FindNode(BinTree->Right,data); return temp; } //假設每個節點值不同 #define LEFT 1 #define RIGHT 0 struct BinTreeNode* InsertNode(struct BinTreeNode* BinTree,int loc,int dir,int data)//插入節點,loc代表插入的數的父節點的值,dir表示方向 { struct BinTreeNode* parent=FindNode(BinTree,loc); if(parent!=NULL){ struct BinTreeNode* temp=CreateNode(data); if(dir==LEFT) parent->Left=temp; else parent->Right=temp; } return BinTree; } //二叉樹前序遍歷的迭代實現,用到棧 /* 思路: 後序不同於前序和中序,後序要訪問完左子樹和右子樹才能訪問節點; 因此遍歷到一個節點,訪不訪問他取決於它的左右子樹是不是均被訪問過了; 需要在結構體中加入一個用來判斷的變數visited,如果其左右子樹均被訪問過,就賦值為1 過程: 當前節點,沿它的左路徑,開始遍歷,直到路徑末尾,開始回溯 回溯過程中的節點的左兒子一定被訪問過了或者不存在,如果其右兒子不存在或者右兒子已經被訪問過,訪問當前節點 如果其右兒子存在,此時以其右兒子為基礎,再去遍歷其左路徑 */ void PostOrderTrversal(struct BinTreeNode* BinTree) { //建棧 struct BinTreeNode* stack[100]; int top=-1; struct BinTreeNode* Temp=BinTree; while(Temp!=NULL||top>=0){ while(Temp!=NULL){//遍歷 (子)樹左路徑 Temp->visited=1; top++; stack[top]=Temp; Temp=Temp->Left; } if(top>=0){ if(stack[top]->Right==NULL||stack[top]->Right->visited==1){//右兒子不存在或者右兒子已經被訪問過 printf("%d ",stack[top]->Element); top--; } else Temp=stack[top]->Right; } } return; } int main() { struct BinTreeNode* BinTree; //先手工建立一個樹 //不提倡此類建樹方法,只是暫時用於測試程式 BinTree=CreateNode(10); BinTree=InsertNode(BinTree,10,1,20); BinTree=InsertNode(BinTree,10,0,30); BinTree=InsertNode(BinTree,30,1,40); BinTree=InsertNode(BinTree,40,0,50); //遍歷 PostOrderTrversal(BinTree); return 0; }