二叉樹先序遍歷(遞迴與非遞迴)及C語言實現
阿新 • • 發佈:2018-12-20
二叉樹先序遍歷的實現思想是:
![](http://data.biancheng.net/uploads/allimg/170830/2-1FS01325394F.png)
圖 1 二叉樹
以圖 1 為例,採用先序遍歷的思想遍歷該二叉樹的過程為:
因此,圖 1 中二叉樹採用先序遍歷得到的序列為:
執行結果:
先序遍歷:
1 2 4 5 3 6 7
1 2 4 5 3 6 7
- 訪問根節點;
- 訪問當前節點的左子樹;
- 若當前節點無左子樹,則訪問當前節點的右子樹;
![](http://data.biancheng.net/uploads/allimg/170830/2-1FS01325394F.png)
圖 1 二叉樹
以圖 1 為例,採用先序遍歷的思想遍歷該二叉樹的過程為:
- 訪問該二叉樹的根節點,找到 1;
- 訪問節點 1 的左子樹,找到節點 2;
- 訪問節點 2 的左子樹,找到節點 4;
- 由於訪問節點 4 左子樹失敗,且也沒有右子樹,因此以節點 4 為根節點的子樹遍歷完成。但節點 2 還沒有遍歷其右子樹,因此現在開始遍歷,即訪問節點 5;
- 由於節點 5 無左右子樹,因此節點 5 遍歷完成,並且由此以節點 2 為根節點的子樹也遍歷完成。現在回到節點 1 ,並開始遍歷該節點的右子樹,即訪問節點 3;
- 訪問節點 3 左子樹,找到節點 6;
- 由於節點 6 無左右子樹,因此節點 6 遍歷完成,回到節點 3 並遍歷其右子樹,找到節點 7;
- 節點 7 無左右子樹,因此以節點 3 為根節點的子樹遍歷完成,同時迴歸節點 1。由於節點 1 的左右子樹全部遍歷完成,因此整個二叉樹遍歷完成;
因此,圖 1 中二叉樹採用先序遍歷得到的序列為:
1 2 4 5 3 6 7
遞迴實現
二叉樹的先序遍歷採用的是遞迴的思想,因此可以遞迴實現,其 C 語言實現程式碼為:#include <stdio.h> #include <string.h> #define TElemType int //構造結點的結構體 typedef struct BiTNode{ TElemType data;//資料域 struct BiTNode *lchild,*rchild;//左右孩子指標 }BiTNode,*BiTree; //初始化樹的函式 void CreateBiTree(BiTree *T){ *T=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->data=1; (*T)->lchild=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->rchild=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->lchild->data=2; (*T)->lchild->lchild=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->lchild->rchild=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->lchild->rchild->data=5; (*T)->lchild->rchild->lchild=NULL; (*T)->lchild->rchild->rchild=NULL; (*T)->rchild->data=3; (*T)->rchild->lchild=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->rchild->lchild->data=6; (*T)->rchild->lchild->lchild=NULL; (*T)->rchild->lchild->rchild=NULL; (*T)->rchild->rchild=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->rchild->rchild->data=7; (*T)->rchild->rchild->lchild=NULL; (*T)->rchild->rchild->rchild=NULL; (*T)->lchild->lchild->data=4; (*T)->lchild->lchild->lchild=NULL; (*T)->lchild->lchild->rchild=NULL; } //模擬操作結點元素的函式,輸出結點本身的數值 void displayElem(BiTNode* elem){ printf("%d ",elem->data); } //先序遍歷 void PreOrderTraverse(BiTree T){ if (T) { displayElem(T);//呼叫操作結點資料的函式方法 PreOrderTraverse(T->lchild);//訪問該結點的左孩子 PreOrderTraverse(T->rchild);//訪問該結點的右孩子 } //如果結點為空,返回上一層 return; } int main() { BiTree Tree; CreateBiTree(&Tree); printf("先序遍歷: \n"); }
1 2 4 5 3 6 7
非遞迴實現
而遞迴的底層實現依靠的是棧儲存結構,因此,二叉樹的先序遍歷既可以直接採用遞迴思想實現,也可以使用棧的儲存結構模擬遞迴的思想實現,其 C 語言實現程式碼為:#include <stdio.h> #include <string.h> #define TElemType int int top=-1;//top變數時刻表示棧頂元素所在位置 //構造結點的結構體 typedef struct BiTNode{ TElemType data;//資料域 struct BiTNode *lchild,*rchild;//左右孩子指標 }BiTNode,*BiTree; //初始化樹的函式 void CreateBiTree(BiTree *T){ *T=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->data=1; (*T)->lchild=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->rchild=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->lchild->data=2; (*T)->lchild->lchild=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->lchild->rchild=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->lchild->rchild->data=5; (*T)->lchild->rchild->lchild=NULL; (*T)->lchild->rchild->rchild=NULL; (*T)->rchild->data=3; (*T)->rchild->lchild=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->rchild->lchild->data=6; (*T)->rchild->lchild->lchild=NULL; (*T)->rchild->lchild->rchild=NULL; (*T)->rchild->rchild=(BiTNode*)malloc(sizeof(BiTNode)); (*T)->rchild->rchild->data=7; (*T)->rchild->rchild->lchild=NULL; (*T)->rchild->rchild->rchild=NULL; (*T)->lchild->lchild->data=4; (*T)->lchild->lchild->lchild=NULL; (*T)->lchild->lchild->rchild=NULL; } //前序遍歷使用的進棧函式 void push(BiTNode** a,BiTNode* elem){ a[++top]=elem; } //彈棧函式 void pop( ){ if (top==-1) { return ; } top--; } //模擬操作結點元素的函式,輸出結點本身的數值 void displayElem(BiTNode* elem){ printf("%d ",elem->data); } //拿到棧頂元素 BiTNode* getTop(BiTNode**a){ return a[top]; } //先序遍歷非遞迴演算法 void PreOrderTraverse(BiTree Tree){ BiTNode* a[20];//定義一個執行結果 先序遍歷:順序棧 BiTNode * p;//臨時指標 push(a, Tree);//根結點進棧 while (top!=-1) { p=getTop(a);//取棧頂元素 pop();//彈棧 while (p) { displayElem(p);//呼叫結點的操作函式 //如果該結點有右孩子,右孩子進棧 if (p->rchild) { push(a,p->rchild); } p=p->lchild;//一直指向根結點最後一個左孩子 } } } int main(){ BiTree Tree; CreateBiTree(&Tree); printf("先序遍歷: \n"); PreOrderTraverse(Tree); }
1 2 4 5 3 6 7