二叉树的遍历 :
1.递归遍历:
-
先序遍历:(遍历过程为: ① 访问根结点; ② 先序遍历其左子树; ③ 先序遍历其右子树)
void preorder_traversal(tree bt){ if (bt){ cout << bt->data ; //无非是该语句位置不同 preorder_traversal(bt->left); preorder_traversal(bt->right); } } //如果想仅输出叶子节点,则仅需对cout语句添加判断if ( !bt->left && !bt->right).
-
中序遍历 :(遍历过程为: ① 中序遍历其左子树; ② 访问根结点; ③ 中序遍历其右子树)
void inorder_traversal(tree bt){ if (bt){ inorder_traversal(bt->left); cout << bt-<data ; //^_~ inorder_traversal(bt->right); } }
-
后序遍历:(遍历过程为: ① 后序遍历其左子树; ② 后序遍历其右子树; ③ 访问根结点)
void postorder_traversal(tree bt){ if (bt){ postorder_traversal(bt->left); postorder_traversal(bt->right); cout << bt->data ; //^_~ } }
2. 非递归遍历:
-
先序遍历:
void preorder_traversal(tree bt){ stack s=create_stack(maxsize); //创建,初始化堆栈s while(bt || !is_empty(s)){ while(bt){ cout << bt->data; //打印结点^_~ push(s,bt); //一直向左并将沿途结点压入堆栈 bt=bt->left; } if (!is_empty){ bt=pop(s); //结点弹出堆栈 bt=bt->right; //转向右子树 } } }
-
中序遍历:
void inorder_traversal(tree bt){ stack s=create_stack(maxsize); //创建,初始化堆栈s while(bt || !is_empty(s)){ while(bt){ push(s,bt); //一直向左并将沿途结点压入堆栈 bt=bt->left; } if (!is_empty){ bt=pop(s); //结点弹出堆栈 cout << bt->data; //打印结点^_~ bt=bt->right; //转向右子树 } } }
-
后序遍历:
/*由于后续遍历比较特殊,需要更换思路,如下: 先把根节点压栈两次,然后出栈,判断是否是第一次出栈, 若是,存入儿子节点,每个节点压栈两次,每次出栈的时候,进行判断*/ void postorder_traversal(tree bt){ stack s=create_stack(maxsize); //创建,初始化堆栈s if (bt){ push(s,bt); //根节点压栈两次 push(s,bt); tree temp=top(s); //top(s)为获取栈顶元素,不出栈 } while (!is_empty(s)){ //根节点第二次出栈后,跳出循环 temp=pop(s); if ( !is_empty(s) && temp==top(s) ){ //栈不空,第一次出栈 if (temp->right){ push(s,temp->right); //右儿子压栈两次 push(s,temp->right); } if (temp->left){ push(s,temp->left); //左儿子压栈两次 push(s,temp->left); } } else cout << temp->data ; //第二次出栈,输出 } }
3. 层序遍历 :
基本过程:先根结点入队,然后从队列中取出一个元素; 访问该元素所指结点;
若该元素所指结点的左、右孩子结点非空,则将其左、右孩子的指针顺序入队。
void levelorder_traversal(tree bt){
queue q=create_queue();
if (bt) add(q,bt);
while(!is_empty(q)){
bt=delete(q);
cout << bt->data ;
if (bt->left) add(q,bt->left);
if (bt->right) add(q,bt->right);
}
}