遍历是二叉树各种操作的基础,上一节给出的遍历算法是递归实现的,本节给出二叉树遍历的非递归实现,非递归实现需要使用前面讲到的数据结构——栈、队列来作为辅助空间。
- 先序遍历
- int preorder_traverse(bitree bt, int (*visit)(elemtype e))
- {
- sqstack s;
- bitree p;
- init_stack(&s);
- p = bt;
- while (p || !is_stack_empty(s)) {
- while (p) { /* 左结点依次进栈,向左走到尽头 */
- visit(p->data);
- push_stack(&s, p);
- p = p->lchild;
- }
- if (!is_stack_empty(s)) {
- pop_stack(&s, &p); /* 出栈 */
- p = p->rchild;
- }
- }
- return OK;
- }
- 中序遍历
- int inorder_traverse(bitree bt, int (*visit)(elemtype e))
- {
- sqstack s;
- bitree p;
- init_stack(&s);
- p = bt;
- while (p || !is_stack_empty(s)) {
- while (p) {
- push_stack(&s, p);
- p = p->lchild;
- }
- if (!is_stack_empty(s)) {
- pop_stack(&s, &p);
- visit(p->data);
- p = p->rchild;
- }
- }
- return OK;
- }
- 后序遍历
- int postorder_traverse(bitree bt, int (*visit)(elemtype e))
- {
- sqstack s;
- bitree p, q;
- init_stack(&s);
- p = bt;
- q = NULL;
- while (p || !is_stack_empty(s)) {
- while (p) {
- push_stack(&s, p);
- p = p->lchild;
- }
- if (!is_stack_empty(s)) {
- get_top(s, &p); /* 取栈顶元素 */
- if (!p->rchild || p->rchild == q) { /* 如果p没有右孩子,或右孩子已经访问过 */
- visit(p->data);
- q = p;
- p = NULL;
- --s.top;/* 退栈 */
- }
- else
- p = p->rchild;
- }
- }
- return OK;
- }
- 层次遍历
- int levelorder_traverse(bitree bt, int (*visit)(elemtype e))
- {
- sqqueue sq;
- bitree cur;
- init_queue(&sq);
- if (bt) {
- in_queue(&sq, bt);
- while (!is_queue_empty(sq)) {
- out_queue(&sq, &cur);
- visit(cur->data);
- if (cur->lchild)
- in_queue(&sq, cur->lchild);
- if (cur->rchild)
- in_queue(&sq, cur->rchild);
- }
- }
- return OK;
- }
- 总结
遍历二叉树算法基本操作是访问结点,不论按哪一种次序进行遍历,对含n个结点的二叉树时间复杂度都为O(n)。