递归很是简单 但也应该掌握其迭代方式的遍历方法
这三种的迭代遍历方法需要通过栈来存储节点 尤其是后序遍历还需要 记录当前节点的右子树是否已被遍历 决定是否遍历当前节点
而其广度遍历 只需要一个队列来顺序记录遍历节点 即可轻松解决问题 主要思想在程序代码中来做说明
前序遍历:遍历结果返回一个vector容器中
std::vector<int> BinaryTree::pre_order_iter(Binary_node *root) { std::vector<int> res; std::stack<Binary_node*> stack_bn; Binary_node *p_top = nullptr; stack_bn.push(root); //从根节点开始将节点入栈 while (!stack_bn.empty()) { p_top = stack_bn.top(); while (p_top) //前序遍历中 首先遍历父节点 所以在此循环中先从根节点开始遍历栈中节点 向左走到尽头 { res.push_back(p_top->val); stack_bn.push(p_top->left); // 一边入栈 一边遍历 p_top = stack_bn.top(); } stack_bn.pop(); //一当前节点的左子树为空 首先弹出空的左子树 if (!stack_bn.empty()) { p_top = stack_bn.top(); stack_bn.pop(); //然后弹出当前节点 因为已经被遍历过了 stack_bn.push(p_top->right); //然后向右走一步 下次循环自此开始 向左到尽头 } } return res; }
中序遍历:遍历结果返回一个vector容器中
std::vector<int> BinaryTree::in_order_iter(Binary_node *root) { std::vector<int> res; std::stack<Binary_node*> stack_bn; Binary_node *p_top = nullptr; stack_bn.push(root); while (!stack_bn.empty()) { p_top = stack_bn.top(); while (p_top) //与前序遍历有像似之处 先往左走到尽头 压入栈中 { stack_bn.push(p_top->left); p_top = stack_bn.top(); } stack_bn.pop(); //弹出最下层的空节点 if (!stack_bn.empty()) { p_top = stack_bn.top(); stack_bn.pop(); res.push_back(p_top->val); //弹出并遍历最左的节点 stack_bn.push(p_top->right);// 往已弹出的遍历节点的右走一步 } } return res; }
//后序遍历 需要记录当前节点和其右节点是否已被遍历的信息 所以定义了如下数据结构
struct snode{ BinaryNode *node; bool rightvisited; snode(BinaryNode *pnode = nullptr, bool visited = false) :node(pnode), rightvisited(visited){} }; void BinaryTree::post_order_iter(BinaryNode *root, std::vector<int> &res) { if (nullptr == root) return; std::stack<snode> stacksnode; snode *ptop = nullptr; BinaryNode *cur = root; stacksnode.push(snode(root)); while (!stacksnode.empty()) { while (cur) { stacksnode.push(snode(cur->left)); cur = cur->left; } if (nullptr==stacksnode.top().node) stacksnode.pop(); if (!stacksnode.empty()) { ptop = &(stacksnode.top()); if (!ptop->node->right || ptop->rightvisited) { res.push_back(ptop->node->val); stacksnode.pop(); } else { ptop->rightvisited = true; stacksnode.push(ptop->node->right); cur = ptop->node->right; } } } }
//广度遍历 如前所述 通过一个队列来依次存储相应节点 完成遍历
std::vector<int> BinaryTree::level_trave(Binary_node *root) { std::vector<int> res; std::queue<Binary_node*> que; Binary_node *p_front; que.push(root); while (!que.empty()) { p_front = que.front(); que.pop(); res.push_back(p_front->val); if (p_front->left) que.push(p_front->left); if (p_front->right) que.push(p_front->right); } return res; }