摘自:http://www.javashuo.com/article/p-mmskqajg-hp.html測試
https://bbs.csdn.net/topics/391882020ui
(只是爲了方便本身複習).net
通常咱們遍歷二叉樹的時候用的是遞歸,用遞歸實現比較簡單,代碼以下:blog
/**************** 基於遞歸實現後序遍歷, *****************/ void PostOrderTraverse(NODE* pRoot) { if (pRoot == NULL) { return; } else { PostOrderTraverse(pRoot->pLeft); PostOrderTraverse(pRoot->pRight); printf("%c", pRoot->chValue); } return; }
經過改變printf語句的位置即可以實現前序和中序遍歷。
下面咱們來看看如何基於棧實現二叉樹的遍歷,能夠把二叉樹分爲root,left,right三個部分
前序遍歷的次序爲root,left,right;
中序遍歷的次序爲left,root,right;
後序遍歷的次序爲left,right,root;
先討論前序遍歷和中序遍歷,顯然能夠經過下面的步驟實現
1.不斷將左子樹入棧,直到左子樹爲空
2.不斷出棧,直到出棧元素的右子樹不爲空
3.若是棧不爲空或當前根結點不爲空,重複步驟1和2
前序遍歷是在步驟1中將入棧的樹的根結點輸出,而中序則是在步驟2中將出棧的樹的根結點輸出
代碼以下:遞歸
/**************** 基於棧實現前序和中序遍歷 *****************/ void OrderTraverseByStack(NODE* pRoot) { NODE* Stack[1000]; int top = 0; while (top > 0 || pRoot != NULL) { for (; pRoot != NULL; pRoot = pRoot->pLeft) { Stack[top++] = pRoot; //前序遍歷 //printf("%c",pRoot->chValue); } for (; pRoot == NULL&&top > 0; pRoot = pRoot->pRight) { pRoot = Stack[--top]; //中序遍歷 //printf("%c", pRoot->chValue); } } }
最後要如何基於棧實現二叉樹的後序遍歷呢?經過觀察能夠發現
前序遍歷的次序爲root,left,right;
後序遍歷的次序爲left,right,root;
將前序遍歷的left和right調換,在倒過來輸出,即可以實現後序遍歷!
所以咱們能夠經過修改一下上面的代碼實現後序遍歷,方法以下:
1,將前序遍歷代碼中的left 和right 對調,並數據存在棧S中。
2,前序遍歷完後,將棧S中的數據逐個出棧並打印便可。
代碼以下:get
/**************** 基於棧實現後序遍歷 *****************/ void PostOrderTraverseByStack(NODE* pRoot) { NODE *StackA[1000],*StackB[1000]; int topA = 0,topB = 0; while (topA > 0 || pRoot != NULL) { for (; pRoot != NULL;pRoot = pRoot->pRight) { StackA[topA++] = pRoot; StackB[topB++] = pRoot; } for (; pRoot == NULL&&topA > 0; pRoot = pRoot->pLeft) { pRoot = StackA[--topA]; } } while (topB > 0) { printf("%c", StackB[--topB]->chValue); } }
下面是測試代碼:io
#include<stdio.h> #include<stdlib.h> #define TREELEN 6 struct NODE { NODE* pLeft; NODE* pRight; char chValue; }; void ReBuild(char* pPreOrder,char* pInOrder,int nTreeLen,NODE** pRoot) { if (pPreOrder == NULL || pInOrder == NULL) { return; } NODE* pTemp =(NODE* )malloc(sizeof(NODE)); pTemp->chValue = *pPreOrder; pTemp->pLeft = NULL; pTemp->pRight = NULL; if (*pRoot == NULL) { *pRoot = pTemp; } if (nTreeLen == 1) { return; } char* pOrgInOrder = pInOrder; char* pLeftEnd = pInOrder; int nTempLen = 0; while (*pPreOrder != *pLeftEnd) { if (pPreOrder == NULL || pLeftEnd == NULL) { return; } nTempLen++; if (nTempLen > nTreeLen) { break; } pLeftEnd++; } int nLeftLen = 0; nLeftLen = (int)(pLeftEnd - pOrgInOrder); int nRightLen = 0; nRightLen = nTreeLen - nLeftLen - 1; if (nLeftLen > 0) { ReBuild(pPreOrder+1, pInOrder, nLeftLen, &((*pRoot)->pLeft)); } if (nRightLen > 0) { ReBuild(pPreOrder + nLeftLen + 1, pInOrder + nLeftLen +1, nRightLen, &((*pRoot)->pRight)); } } /**************** 基於遞歸實現後序遍歷, *****************/ void PostOrderTraverse(NODE* pRoot) { if (pRoot == NULL) { return; } else { PostOrderTraverse(pRoot->pLeft); PostOrderTraverse(pRoot->pRight); printf("%c", pRoot->chValue); } return; } /**************** 基於棧實現前序和中序遍歷 *****************/ void OrderTraverseByStack(NODE* pRoot) { NODE* Stack[1000]; int top = 0; while (top > 0 || pRoot != NULL) { for (; pRoot != NULL; pRoot = pRoot->pLeft) { Stack[top++] = pRoot; //前序遍歷 //printf("%c",pRoot->chValue); } for (; pRoot == NULL&&top > 0; pRoot = pRoot->pRight) { pRoot = Stack[--top]; //中序遍歷 printf("%c", pRoot->chValue); } } } /**************** 基於棧實現後序遍歷 *****************/ void PostOrderTraverseByStack(NODE* pRoot) { NODE *StackA[1000],*StackB[1000]; int topA = 0,topB = 0; while (topA > 0 || pRoot != NULL) { for (; pRoot != NULL;pRoot = pRoot->pRight) { StackA[topA++] = pRoot; StackB[topB++] = pRoot; } for (; pRoot == NULL&&topA > 0; pRoot = pRoot->pLeft) { pRoot = StackA[--topA]; } } while (topB > 0) { printf("%c", StackB[--topB]->chValue); } } int main() { NODE* pRoot = NULL; char pre[TREELEN] = { 'a','b','d','e','c','f' }; char in[TREELEN] = { 'd','b','e','a','f','c' }; ReBuild(pre, in, TREELEN, &pRoot); printf("\n經過棧實現的中序遍歷結果:\n"); OrderTraverseByStack(pRoot); printf("\n經過遞歸實現的後序遍歷結果:\n"); PostOrderTraverse(pRoot); printf("\n經過棧實現的後序遍歷結果:\n"); PostOrderTraverseByStack(pRoot); getchar(); return 0; }