DS之遍曆二叉樹,ds曆二叉樹
在二叉樹的一些應用中,常常要求在樹中尋找具有某種特徵的結點,或者對樹中全部結點逐一進行某種處理。這就提出了一個遍曆二叉樹的問題,即如何按某條搜尋路徑巡訪樹中的每個結點,使得每個結點均被訪問一次,而且僅被訪問一次。
由二叉樹的遞迴定義可知,二叉樹是由三個基本單元構成的:根結點,左子樹和右子樹。若能依次遍曆這三部分,便是遍曆了整個二叉樹。若限定先左後右的順序,則遍曆二叉樹通常有三種演算法:先序,中序,後序。
先序遍曆二叉樹的操作定義為:
若二叉樹為空白,則空操作;否則;
(1)訪問根結點;(2)先序遍曆左子樹;(3)先序遍曆右子樹。
中序遍曆二叉樹的操作定義為:
若二叉樹為空白,則空操作;否則;
(1)中序遍曆左子樹;(2)訪問根結點;(3)中序遍曆右子樹。
後序遍曆二叉樹的操作定義為:
若二叉樹為空白,則空操作;否則;
(1)後序遍曆左子樹;(2)後序遍曆右子樹;(3)訪問根結點。
對於二叉樹的遍曆我們在二叉樹的二叉鏈表上實現。在二叉樹的二叉鏈表的基本操作中也介紹了四種遍曆方法,我們就來實現前三種遍曆方法。在遍曆函數的參數中除了一個指標參數外,還有一個指向函數的指標參數。這個函數最簡單的實現為Visit()函數。這個函數最簡單的代碼為:
Status printElement(TElemType e)//最簡單的Visit()函數{cout<<e<<",";return OK;}
再者就是需要構建二叉表(先序輸入資料元素)的代碼:
Status CreateBiTree(BiTree &T)//按先序次序輸入二叉樹中結點的值(一個字元),空白字元表示空樹,構造二叉鏈表表示的二叉樹T{int i=0; char a[100]; cin>>a[i]; if(a[i]=='#') T=NULL; else{ if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) { exit(OVERFLOW); } T->data=a[i];//產生根結點 CreateBiTree(T->lchild); //構造左子樹 CreateBiTree(T->rchild); //構造右子樹 } return OK;}
先來看看二叉鏈表的先序遍曆代碼:
Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//先序遍曆二叉樹{ if(T) { if(Visit(T->data)) {if(PreOrderTraverse(T->lchild,Visit)) {if(PreOrderTraverse(T->rchild,Visit)){return OK;}} return ERROR;} } else { return OK; }}
再來看二叉鏈表的中序遍曆代碼:
Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//中序遍曆二叉樹{ if(T) { if(InOrderTraverse(T->lchild,Visit)) { if(Visit(T->data)) { if(InOrderTraverse(T->rchild,Visit)) { return OK; } } return ERROR; } } else { return OK; }}
最後來看二叉鏈表的後序遍曆代碼:
Status PostOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//後序遍曆二叉樹{ if(T){ if(PostOrderTraverse(T->lchild,Visit)) { if(PostOrderTraverse(T->rchild,Visit)) { if(Visit(T->data)) {return OK; } } return ERROR; } }else{ return OK;}}
完整的代碼為:
#include <iostream>#include <Cstdlib>using namespace std;#define OK 1#define ERROR 0#define OVERFLOW -2typedef char TElemType;typedef int Status;typedef struct BiTNode{ TElemType data; struct BiTNode *lchild,*rchild; //左右孩子指標}BiTNode,*BiTree;Status CreateBiTree(BiTree &T)//按先序次序輸入二叉樹中結點的值(一個字元),空白字元表示空樹,構造二叉鏈表表示的二叉樹T{int i=0; char a[100]; cin>>a[i]; if(a[i]=='#') T=NULL; else{ if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) { exit(OVERFLOW); } T->data=a[i];//產生根結點 CreateBiTree(T->lchild); //構造左子樹 CreateBiTree(T->rchild); //構造右子樹 } return OK;}Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//先序遍曆二叉樹{ if(T) { if(Visit(T->data)) {if(PreOrderTraverse(T->lchild,Visit)) {if(PreOrderTraverse(T->rchild,Visit)){return OK;}} return ERROR;} } else { return OK; }}Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//中序遍曆二叉樹{ if(T) { if(InOrderTraverse(T->lchild,Visit)) { if(Visit(T->data)) { if(InOrderTraverse(T->rchild,Visit)) { return OK; } } return ERROR; } } else { return OK; }} Status PostOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//後序遍曆二叉樹{ if(T){ if(PostOrderTraverse(T->lchild,Visit)) { if(PostOrderTraverse(T->rchild,Visit)) { if(Visit(T->data)) {return OK; } } return ERROR; } }else{ return OK;}}Status printElement(TElemType e)//最簡單的Visit()函數{cout<<e<<",";return OK;}int main(){ BiTree T;//構建二叉樹 CreateBiTree(T);//先序輸入二叉樹的資料元素cout<<"先序遍曆二叉樹的輸出:"; PreOrderTraverse(T,printElement); cout<<endl;cout<<"中序遍曆二叉樹的輸出:";InOrderTraverse(T,printElement); cout<<endl;cout<<"後序遍曆二叉樹的輸出:"; PostOrderTraverse(T,printElement); cout<<endl;return 0;}
輸入的資料:先序輸入ABC##DE#G##F###(#代表空)
這棵樹的圖為:
輸出的結果為: