如何用棧遍歷二叉樹

摘自: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;
}
相關文章
相關標籤/搜索