// 递归遍历 void VisitTree_Recursive(const TreeNode *root, void (*visit_func)(const TreeNode *), int visit_mode = VISIT_PREORDER) { if (! root || !visit_func) return; if (VISIT_PREORDER == visit_mode) visit_func(root); if (root->left) VisitTree_Recursive(root->left, visit_func, visit_mode); if (VISIT_INORDER == visit_mode) visit_func(root); if (root->right) VisitTree_Recursive(root->right, visit_func, visit_mode); if (VISIT_POSTORDER == visit_mode) visit_func(root); }
// 非递归遍历实现 void VisitTree_PreOrder(const TreeNode *root, void (*visit_func)(const TreeNode *)) { // 前序遍历 // 可以利用类似的思路,利用第二个栈,把push次序逆过来,就形成了后序遍历 // 见 VisitTree_PostOrder_v2 if (!root || !visit_func) return; const TreeNode *cur = NULL; std::stack<const TreeNode *> st; st.push(root); while (!st.empty()) { cur = st.top(); st.pop(); visit_func(cur); // 先push右节点 // 这是为了保证左节点在下次循环首先被pop出来处理, // 同时也被左节点的子节点覆盖在上面,满足处理完左子树, // 再处理右子树的特点 if (cur->right) st.push(cur->right); if (cur->left) st.push(cur->left); } }
void VisitTree_InOrder(const TreeNode *root, void (*visit_func)(const TreeNode *)) { // 中序遍历 if (!root || !visit_func) return; const TreeNode *cur = NULL; std::stack<const TreeNode *> st; st.push(root); while (!st.empty()) { // 向左走到尽头 while (st.top()->left) st.push(st.top()->left); // 不断退栈,访问节点,试图找到右出路 do { cur = st.top(); st.pop(); visit_func(cur); // 右结点存在,切换成外循环走左 if (cur->right) { st.push(cur->right); break; } } while (!st.empty()); } }
void list_retraversal(List *L, void (*visit_func)(void *)) { ListNode *p = L->tail; while (!IS_NULL(p)) { visit_func(p->value); p = p->prev; } }
void list_traversal(List *L, void (*visit_func)(void *)) { ListNode *p = L->head; while (!IS_NULL(p)) { visit_func(p->value); p = p->next; } }
void decl_collector::visit(ast* n) { datatype_util util(m()); m_todo.push_back(n); while (!m_todo.empty()) { n = m_todo.back(); m_todo.pop_back(); if (!m_visited.is_marked(n)) { switch(n->get_kind()) { case AST_APP: { app * a = to_app(n); for (expr* arg : *a) { m_todo.push_back(arg); } m_todo.push_back(a->get_decl()); break; } case AST_QUANTIFIER: { quantifier * q = to_quantifier(n); unsigned num_decls = q->get_num_decls(); for (unsigned i = 0; i < num_decls; ++i) { m_todo.push_back(q->get_decl_sort(i)); } m_todo.push_back(q->get_expr()); for (unsigned i = 0; i < q->get_num_patterns(); ++i) { m_todo.push_back(q->get_pattern(i)); } break; } case AST_SORT: visit_sort(to_sort(n)); break; case AST_FUNC_DECL: { func_decl * d = to_func_decl(n); for (sort* srt : *d) { m_todo.push_back(srt); } m_todo.push_back(d->get_range()); visit_func(d); break; } case AST_VAR: break; default: UNREACHABLE(); } m_visited.mark(n, true); } } }
void decl_collector::visit(ast* n) { ptr_vector<ast> todo; todo.push_back(n); while (!todo.empty()) { n = todo.back(); todo.pop_back(); if (!m_visited.is_marked(n)) { m_visited.mark(n, true); switch(n->get_kind()) { case AST_APP: { app * a = to_app(n); for (unsigned i = 0; i < a->get_num_args(); ++i) { todo.push_back(a->get_arg(i)); } todo.push_back(a->get_decl()); break; } case AST_QUANTIFIER: { quantifier * q = to_quantifier(n); unsigned num_decls = q->get_num_decls(); for (unsigned i = 0; i < num_decls; ++i) { todo.push_back(q->get_decl_sort(i)); } todo.push_back(q->get_expr()); for (unsigned i = 0; i < q->get_num_patterns(); ++i) { todo.push_back(q->get_pattern(i)); } break; } case AST_SORT: visit_sort(to_sort(n)); break; case AST_FUNC_DECL: { func_decl * d = to_func_decl(n); for (unsigned i = 0; i < d->get_arity(); ++i) { todo.push_back(d->get_domain(i)); } todo.push_back(d->get_range()); visit_func(d); break; } case AST_VAR: break; default: UNREACHABLE(); } } } }
void VisitTree_PostOrder(const TreeNode *root, void (*visit_func)(const TreeNode *)) { // 后序遍历 if (!root || !visit_func) return; const TreeNode *cur = NULL; // pre指向上次处理的结点,以便判断从左/右子树处理完成回到当前结点 const TreeNode *pre = NULL; std::stack<const TreeNode *> st; st.push(root); while (!st.empty()) { // 向左走到尽头 while (st.top()->left) st.push(st.top()->left); // 不断退栈,判断从右子树返回再访问节点,不满足访问条件, // 把右结点加入栈,走外循环 do { pre = cur; cur = st.top(); // 右结点不存在或者上次已经处理了右结点,表明当前结点可以退栈和处理了 if (cur->right == NULL || cur->right == pre) { st.pop(); visit_func(cur); continue; } // 到了这里,表明右子树存在,并且还没被访问 // push右结点,走外循环逻辑 st.push(cur->right); break; } while (!st.empty()); } }
void VisitTree_PostOrder_v2(const TreeNode *root, void (*visit_func)(const TreeNode *)) { // 后序遍历 双栈法 // 思路类似前序遍历的非递归法 // 顺序栈访问顺序:根->右->左,对逆序栈,则是左->右->根, // 正是后序遍历需要的顺序 if (!root || !visit_func) return; const TreeNode *cur = NULL; std::stack<const TreeNode *> st; st.push(root); std::stack<const TreeNode *> st_back; while (!st.empty()) { cur = st.top(); st.pop(); // push倒序栈 st_back.push(cur); // 后push右,保证右先被处理 if (cur->left) st.push(cur->left); if (cur->right) st.push(cur->right); } while (!st_back.empty()) { visit_func(st_back.top()); st_back.pop(); } }