1 二叉樹結點
2 先序遍曆二叉樹
3 中序遍曆二叉樹
4 後序遍曆二叉樹
5 測試範例
1 二叉樹結點
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode *m_pLeft;
BinaryTreeNode *m_pRight;
};
2 先序遍曆二叉樹
先序遍曆二叉樹遞迴演算法定義為:
若二叉樹為空白,則空操作;否則(1)訪問根節點;(2)先序遍曆左子樹;(3)後序遍曆右子樹;
代碼如下:
/* 遞迴先序遍曆 */void PreOrderTraverseTree(BinaryTreeNode *pRoot){if (pRoot != NULL){cout << pRoot->m_nValue << " ";PreOrderTraverseTree(pRoot->m_pLeft);PreOrderTraverseTree(pRoot->m_pRight);}}
先序遍曆二叉樹的非遞迴演算法定義為:
我們首先建立一個堆棧stack<BinaryTreeNode *>nodes,首先讓根節點入棧。
然後進入一個while迴圈,即 while(!nodes.empty()),每次彈出一個節點。遍曆該節點的值,然後將其節點的右孩子入棧,再次將其節點的左孩子入棧。
直至while迴圈結束。
代碼如下:
/* 非遞迴先序遍曆 */void PreOrderTraverseTreeNoRecursive(BinaryTreeNode *pRoot){if (pRoot == NULL){return;}stack<BinaryTreeNode *> nodes;nodes.push(pRoot);while (!nodes.empty()){BinaryTreeNode *pNode = nodes.top();nodes.pop();cout << pNode->m_nValue << " ";if (pNode->m_pRight != NULL){nodes.push(pNode->m_pRight);}if (pNode->m_pLeft != NULL){nodes.push(pNode->m_pLeft);}}}
3 中序遍曆二叉樹
中序遍曆二叉樹的遞迴演算法如下:
若二叉樹為空白,則空操作;否則(1)中序遍曆左子樹;(2)訪問根節點;(3)中序遍曆右子樹;
代碼如下:
/* 遞迴中序遍曆 */void InOrderTraverseTree(BinaryTreeNode *pRoot){if (pRoot != NULL){InOrderTraverseTree(pRoot->m_pLeft);cout << pRoot->m_nValue << " ";InOrderTraverseTree(pRoot->m_pRight);}}
中序遍曆二叉樹的非遞迴演算法如下:
/* 非遞迴中序遍曆 */void InOrderTraverseTreeNoRecursive(BinaryTreeNode *pRoot){if (pRoot == NULL){return;}stack<BinaryTreeNode *> nodes;BinaryTreeNode *pCurrent = pRoot;while (!nodes.empty() || pCurrent != NULL){if (pCurrent != NULL){nodes.push(pCurrent);pCurrent = pCurrent->m_pLeft;}else{pCurrent = nodes.top();nodes.pop();cout << pCurrent->m_nValue << " ";pCurrent = pCurrent->m_pRight;}}}
4 後序遍曆二叉樹
後序遍曆二叉樹的遞迴演算法如下:
若二叉樹為空白,則空操作;否則(1)後序遍曆左子樹;(2)後序遍曆右子樹;(3)訪問根節點;
/* 遞迴後序遍曆 */void PostOrderTraverseTree(BinaryTreeNode *pRoot){if (pRoot != NULL){PostOrderTraverseTree(pRoot->m_pLeft);PostOrderTraverseTree(pRoot->m_pRight);cout << pRoot->m_nValue << " ";}}
後序遍曆二叉樹的非遞迴演算法如下:
/* 非遞迴後序遍曆 */void PostOrderTraverseTreeNoRecursive(BinaryTreeNode *pRoot){if (pRoot == NULL){return;}stack<BinaryTreeNode *> traverseNodes;stack<BinaryTreeNode *> nodes;traverseNodes.push(pRoot);while (!traverseNodes.empty()){BinaryTreeNode *pNode = traverseNodes.top();traverseNodes.pop();if (pNode->m_pLeft != NULL){traverseNodes.push(pNode->m_pLeft);}if (pNode->m_pRight != NULL){traverseNodes.push(pNode->m_pRight);}nodes.push(pNode);}while (!nodes.empty()){BinaryTreeNode *pNode = nodes.top();nodes.pop();cout << pNode->m_nValue << " ";}}
5 測試範例
檔案 BinaryTree.h
struct BinaryTreeNode {int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; };BinaryTreeNode* CreateBinaryTreeNode(int value);void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight);void PrintTreeNode(BinaryTreeNode* pNode);void PrintTree(BinaryTreeNode* pRoot);void DestroyTree(BinaryTreeNode* pRoot);
檔案 BinaryTree.cpp
#include "BinaryTree.h"#include <cstdio>BinaryTreeNode* CreateBinaryTreeNode(int value){BinaryTreeNode* pNode = new BinaryTreeNode();pNode->m_nValue = value;pNode->m_pLeft = NULL;pNode->m_pRight = NULL;return pNode;}void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight){if(pParent != NULL){pParent->m_pLeft = pLeft;pParent->m_pRight = pRight;}}void PrintTreeNode(BinaryTreeNode* pNode){if(pNode != NULL){printf("value of this node is: %d\n", pNode->m_nValue);if(pNode->m_pLeft != NULL)printf("value of its left child is: %d.\n", pNode->m_pLeft->m_nValue);elseprintf("left child is null.\n");if(pNode->m_pRight != NULL)printf("value of its right child is: %d.\n", pNode->m_pRight->m_nValue);elseprintf("right child is null.\n");}else{printf("this node is null.\n");}printf("\n");}void PrintTree(BinaryTreeNode* pRoot){PrintTreeNode(pRoot);if(pRoot != NULL){if(pRoot->m_pLeft != NULL)PrintTree(pRoot->m_pLeft);if(pRoot->m_pRight != NULL)PrintTree(pRoot->m_pRight);}}void DestroyTree(BinaryTreeNode* pRoot){if(pRoot != NULL){BinaryTreeNode* pLeft = pRoot->m_pLeft;BinaryTreeNode* pRight = pRoot->m_pRight;delete pRoot;pRoot = NULL;DestroyTree(pLeft);DestroyTree(pRight);}}
檔案 TraverseTree.cpp
#include "BinaryTree.h"#include <iostream>#include <stack>using namespace std;/* 遞迴先序遍曆 */void PreOrderTraverseTree(BinaryTreeNode *pRoot){if (pRoot != NULL){cout << pRoot->m_nValue << " ";PreOrderTraverseTree(pRoot->m_pLeft);PreOrderTraverseTree(pRoot->m_pRight);}}/* 非遞迴先序遍曆 */void PreOrderTraverseTreeNoRecursive(BinaryTreeNode *pRoot){if (pRoot == NULL){return;}stack<BinaryTreeNode *> nodes;nodes.push(pRoot);while (!nodes.empty()){BinaryTreeNode *pNode = nodes.top();nodes.pop();cout << pNode->m_nValue << " ";if (pNode->m_pRight != NULL){nodes.push(pNode->m_pRight);}if (pNode->m_pLeft != NULL){nodes.push(pNode->m_pLeft);}}}/* 遞迴中序遍曆 */void InOrderTraverseTree(BinaryTreeNode *pRoot){if (pRoot != NULL){InOrderTraverseTree(pRoot->m_pLeft);cout << pRoot->m_nValue << " ";InOrderTraverseTree(pRoot->m_pRight);}}/* 非遞迴中序遍曆 */void InOrderTraverseTreeNoRecursive(BinaryTreeNode *pRoot){if (pRoot == NULL){return;}stack<BinaryTreeNode *> nodes;BinaryTreeNode *pCurrent = pRoot;while (!nodes.empty() || pCurrent != NULL){if (pCurrent != NULL){nodes.push(pCurrent);pCurrent = pCurrent->m_pLeft;}else{pCurrent = nodes.top();nodes.pop();cout << pCurrent->m_nValue << " ";pCurrent = pCurrent->m_pRight;}}}/* 遞迴後序遍曆 */void PostOrderTraverseTree(BinaryTreeNode *pRoot){if (pRoot != NULL){PostOrderTraverseTree(pRoot->m_pLeft);PostOrderTraverseTree(pRoot->m_pRight);cout << pRoot->m_nValue << " ";}}/* 非遞迴後序遍曆 */void PostOrderTraverseTreeNoRecursive(BinaryTreeNode *pRoot){if (pRoot == NULL){return;}stack<BinaryTreeNode *> traverseNodes;stack<BinaryTreeNode *> nodes;traverseNodes.push(pRoot);while (!traverseNodes.empty()){BinaryTreeNode *pNode = traverseNodes.top();traverseNodes.pop();if (pNode->m_pLeft != NULL){traverseNodes.push(pNode->m_pLeft);}if (pNode->m_pRight != NULL){traverseNodes.push(pNode->m_pRight);}nodes.push(pNode);}while (!nodes.empty()){BinaryTreeNode *pNode = nodes.top();nodes.pop();cout << pNode->m_nValue << " ";}}void Test(const char *testName, BinaryTreeNode *pRoot){if (testName != NULL){cout << testName << " : " << endl;}cout << "遞迴先序遍曆: " ;PreOrderTraverseTree(pRoot);cout << endl;cout << "非遞迴先序遍曆:";PreOrderTraverseTreeNoRecursive(pRoot);cout << endl;cout << "遞迴中序遍曆: ";InOrderTraverseTree(pRoot);cout << endl;cout << "非遞迴中序遍曆:";InOrderTraverseTreeNoRecursive(pRoot);cout << endl;cout << "遞迴後序遍曆: ";PostOrderTraverseTree(pRoot);cout << endl;cout << "非遞迴後序遍曆:";PostOrderTraverseTreeNoRecursive(pRoot);cout << endl;}void Test1(){BinaryTreeNode *pNode1 = CreateBinaryTreeNode(1);BinaryTreeNode *pNode2 = CreateBinaryTreeNode(2);BinaryTreeNode *pNode3 = CreateBinaryTreeNode(3);BinaryTreeNode *pNode4 = CreateBinaryTreeNode(4);BinaryTreeNode *pNode5 = CreateBinaryTreeNode(5);BinaryTreeNode *pNode6 = CreateBinaryTreeNode(6);ConnectTreeNodes(pNode1, pNode2, pNode3);ConnectTreeNodes(pNode2, pNode4, pNode5);ConnectTreeNodes(pNode3, pNode6, NULL);Test("Test1", pNode1);DestroyTree(pNode1);}void Test2(){BinaryTreeNode *pNode1 = CreateBinaryTreeNode(1);BinaryTreeNode *pNode2 = CreateBinaryTreeNode(2);BinaryTreeNode *pNode3 = CreateBinaryTreeNode(3);BinaryTreeNode *pNode4 = CreateBinaryTreeNode(4);BinaryTreeNode *pNode5 = CreateBinaryTreeNode(5);ConnectTreeNodes(pNode1, pNode2, NULL);ConnectTreeNodes(pNode2, pNode3, NULL);ConnectTreeNodes(pNode3, pNode4, NULL);ConnectTreeNodes(pNode4, pNode5, NULL);Test("Test2", pNode1);DestroyTree(pNode1);}void Test3(){BinaryTreeNode *pNode1 = CreateBinaryTreeNode(1);BinaryTreeNode *pNode2 = CreateBinaryTreeNode(2);BinaryTreeNode *pNode3 = CreateBinaryTreeNode(3);BinaryTreeNode *pNode4 = CreateBinaryTreeNode(4);BinaryTreeNode *pNode5 = CreateBinaryTreeNode(5);ConnectTreeNodes(pNode1, NULL, pNode2);ConnectTreeNodes(pNode2, NULL, pNode3);ConnectTreeNodes(pNode3, NULL, pNode4);ConnectTreeNodes(pNode4, NULL, pNode5);Test("Test3", pNode1);DestroyTree(pNode1);}void Test4(){BinaryTreeNode *pNode1 = CreateBinaryTreeNode(1);Test("Test4", pNode1);DestroyTree(pNode1);}void Test5(){Test("Test5", NULL);}int main(){Test1();Test2();Test3();Test4();Test5();}
測試結果: