예제 #1
0
// 递归遍历
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);
}
예제 #2
0
// 非递归遍历实现
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);
	}
}
예제 #3
0
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());
	}

}
예제 #4
0
파일: list.c 프로젝트: hoohack/KeepCoding
void list_retraversal(List *L, void (*visit_func)(void *))
{
    ListNode *p = L->tail;
    while (!IS_NULL(p)) {
        visit_func(p->value);
        p = p->prev;
    }
}
예제 #5
0
파일: list.c 프로젝트: hoohack/KeepCoding
void list_traversal(List *L, void (*visit_func)(void *))
{
    ListNode *p = L->head;
    while (!IS_NULL(p)) {
        visit_func(p->value);
        p = p->next;
    }
}
예제 #6
0
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);
        }
    }
}
예제 #7
0
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();
            }
        }
    }
}
예제 #8
0
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());
	}

}
예제 #9
0
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();
	}
}