RT, 部分参考了《剑指offer》
#pragma once #include <iostream> #include <vector> #include <stack> using namespace std; struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; class BinaryTree { public: BinaryTreeNode* Construct(int preorder[], int inorder[], int length); // 根据先序、中序结果构造二叉树 BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreOrder, int* startInorder, int* endInorder);
// 递归, 遍历的结果放入vector中 void PreOrderTraverseRecursion(BinaryTreeNode* root, vector<int>& preOrder); void InOrderTraverseRecursion(BinaryTreeNode* root, vector<int>& inOrder); void PostOrderTraverseRecursion(BinaryTreeNode* root, vector<int>& postOrder); // 非递归,遍历的结果放入vector中
void PreOrderTraverseStack(BinaryTreeNode* root, vector<int>& preOrder);
void InOrderTraverseStack(BinaryTreeNode* root, vector<int>& inOrder);
void PostOrderTraverseStack(BinaryTreeNode* root, vector<int>& postOrder);
public: BinaryTree(void); ~BinaryTree(void); };
#include "BinaryTree.h" BinaryTree::BinaryTree(void) { } BinaryTree::~BinaryTree(void) { } BinaryTreeNode* BinaryTree::Construct(int preorder[], int inorder[], int length) { if (preorder == NULL || inorder == NULL || length < 0) { return NULL; } return ConstructCore(preorder, preorder + length - 1, inorder, inorder + length - 1); } BinaryTreeNode* BinaryTree::ConstructCore(int* startPreorder, int* endPreorder, int* startInorder, int* endInorder) { int rootValue = startPreorder[0]; BinaryTreeNode* root = new BinaryTreeNode(); root->m_nValue = rootValue; root->m_pLeft = root->m_pRight = NULL; if (startPreorder == endPreorder) { if (startInorder == endInorder && *startInorder == *endInorder) // 叶子结点 { return root; } else throw std::exception("Invalid input."); } // 在中序中找到该value所在位置 int* rootInorder = startInorder; while (rootInorder <= endInorder && *rootInorder != rootValue) { rootInorder++; } if (rootInorder > endInorder) { throw std::exception("Invalid input."); } int leftLength = rootInorder - startInorder; if (leftLength > 0) // 左子树 { root->m_pLeft = ConstructCore(startPreorder + 1, startPreorder + leftLength, startInorder, rootInorder -1); } if(endInorder - rootInorder > leftLength) // 有右子树 { root->m_pRight = ConstructCore(startPreorder + leftLength + 1, endPreorder, rootInorder + 1, endInorder); } return root; } void BinaryTree::PreOrderTraverseRecursion(BinaryTreeNode* root, vector<int>& preOrder) { BinaryTreeNode* current = root; // 先序递归遍历 if (current != NULL) { preOrder.push_back(current->m_nValue); PreOrderTraverseRecursion(current->m_pLeft, preOrder); PreOrderTraverseRecursion(current->m_pRight, preOrder); } } void BinaryTree::InOrderTraverseRecursion(BinaryTreeNode* root, vector<int>& inOrder) { BinaryTreeNode* current = root; // 中序递归遍历 if (current != NULL) { InOrderTraverseRecursion(current->m_pLeft, inOrder); inOrder.push_back(current->m_nValue); InOrderTraverseRecursion(current->m_pRight, inOrder); } } void BinaryTree::PostOrderTraverseRecursion(BinaryTreeNode* root, vector<int>& postOrder) { BinaryTreeNode* current = root; // 后序递归遍历 if (current != NULL) { PostOrderTraverseRecursion(current->m_pLeft, postOrder); PostOrderTraverseRecursion(current->m_pRight, postOrder); postOrder.push_back(current->m_nValue); } } void BinaryTree::PreOrderTraverseStack(BinaryTreeNode* root, vector<int>& preOrder) { // 非递归 先序遍历 BinaryTreeNode* current = root; stack<BinaryTreeNode*> travelStack; while (current || !travelStack.empty()) { if (current) { travelStack.push(current); preOrder.push_back(current->m_nValue); // 先序 current = current->m_pLeft; } else // 左子树为NULL { current = travelStack.top(); current = current->m_pRight; travelStack.pop(); // 根出栈 } } } void BinaryTree::InOrderTraverseStack(BinaryTreeNode* root, vector<int>& inOrder) { // 非递归 中序遍历 BinaryTreeNode* current = root; stack<BinaryTreeNode*> travelStack; while (current || !travelStack.empty()) { if (current) { travelStack.push(current); current = current->m_pLeft; } else { current = travelStack.top(); inOrder.push_back(current->m_nValue); // 中序 current = current->m_pRight; travelStack.pop(); } } } void BinaryTree::PostOrderTraverseStack(BinaryTreeNode* root, vector<int>& postOrder) { // 非递归 后序遍历 int flag[1000]; // 使用一个标记,标记该node的右结点是否被访问过 stack<BinaryTreeNode* > travelStack; BinaryTreeNode* current = root; while(current) // 先左 { travelStack.push(current); flag[travelStack.size()] = 0; current = current->m_pLeft; } while(!travelStack.empty()) { current = travelStack.top(); while (current->m_pRight && flag[travelStack.size()] == 0) // 右子树未被访问过 { flag[travelStack.size()] = 1; // 标记当前结点的右子节点被访问过了 current = current->m_pRight; // 右子树 while(current) // 先左 { travelStack.push(current); flag[travelStack.size()] = 0; current = current->m_pLeft; } current = travelStack.top(); } // current的右子树为NULL 或 已被访问过 postOrder.push_back(current->m_nValue); // 后序访问根结点 travelStack.pop(); // 出栈 } }
#include <iostream> #include "BinaryTree.h" using namespace std; int main(int agrc, char* argv[]) { BinaryTree bt; int preOrder[] = {1,2,4,7,3,5,6,8}; int inOrder[] = {4,7,2,1,5,3,8,6}; BinaryTreeNode* root = bt.Construct(preOrder, inOrder, 8); vector<int> preV1; vector<int> preV2; vector<int> inV1; vector<int> inV2; vector<int> postV1; vector<int> postV2; bt.PreOrderTraverseRecursion(root, preV1); bt.PreOrderTraverseStack(root, preV2); bt.InOrderTraverseRecursion(root, inV1); bt.InOrderTraverseStack(root, inV2); bt.PostOrderTraverseRecursion(root, postV1); bt.PostOrderTraverseStack(root, postV2); return 0; }