二叉树遍历

一、先序遍历:遍历顺序为根-左-右
1、递归方式:

void recur_preorder(TreeNode *root){
    if(root == NULL) return;
    cout<val<<" ";
    recur_preorder(root->lchild);
    recur_preorder(root->rchild);
}

2、非递归方式:
遍历步骤:
①、根节点先进栈。
②、当栈不空时循环,每次弹出一个结点并访问,若结点右孩子存在,则右孩子进栈,若结点左孩子存在,则左孩子进栈(入栈顺序为先右后左,最后访问顺序就为先左后右)。

void unrecur_preorder(TreeNode *root){
    stack st;
    st.push(root);
    while(!st.empty()){
        root = st.top();
        cout<val<<" ";
        st.pop();
        if(root->rchild) st.push(root->rchild);
        if(root->lchild) st.push(root->lchild);
    }
}

二、中序遍历:遍历顺序为左-根-右
1、递归方式:

void recur_inorder(TreeNode *root){
    if(root == NULL) return;
    recur_inorder(root->lchild);
    cout<val<<" ";
    recur_inorder(root->rchild);
}

2、非递归方式
遍历步骤:
①、将根结点入栈
②、将左边界压入栈中,即不停的令root = root->left,st.push(root);
③、若root为空,则从栈中弹出一个结点并访问,并令root = root->right,继续重复步骤②。
④、当栈为空并且root也为空时,循环结束。

void unrecur_inorder(TreeNode *root){
    stack st;
    while (!st.empty() || root!=NULL){
        if(root){
            st.push(root);
            root = root->lchild;
        }
        else{
            root = st.top();
            cout<val<<" ";
            st.pop();
            root = root->rchild;
        }
    }
}

三、后序遍历:遍历顺序为左-右-根
1、递归方式:

void recur_postprder(TreeNode *root){
    if(root == NULL) return;
    recur_postprder(root->lchild);
    recur_postprder(root->rchild);
    cout<val<<" ";
}

2、非递归方式:
单栈遍历比较麻烦,在这里采用双栈遍历。
在先序遍历过程中,右孩子进栈后左孩子再进栈,输出结果为根-左-右。
我们令左孩子先进栈,右孩子再进栈,则输出结果为根-右-左,将其放入另一个栈中,然后输出,结果即为左-右-根。

void unrecur_postprder(TreeNode *root){
    stack st1;
    stack st2;
    st1.push(root);
    while (!st1.empty()){
        root = st1.top();
        st1.pop();
        st2.push(root);
        if(root->lchild) st1.push(root->lchild);
        if(root->rchild) st1.push(root->rchild);
    }
    while(!st2.empty()){
        cout<

四、层次遍历
遍历步骤:
①、根结点入队
②、队列不空时循环,弹出队首元素并访问,若其左孩子存在,左孩子入队,若其右孩子存在,右孩子入队

Notes:因为层次遍历过程中大多数操作都只和某一层数据相关,例如求二叉树的最大深度,最小深度,将每一层的数据分别输出。所以我在每一层的最后入队一个空结点表示这一层结束。需要操作哪一层加个变量level即可。

void levelorder2(TreeNode *root){
    queue q;
    q.push(root);
    q.push(NULL);
    while(!q.empty()){
        TreeNode *p = q.front();
        q.pop();
        if(!p){
            if(q.size()>0) q.push(NULL); //在每一层结束时,若队列不为空,则push一个NULL来标记当前层的末尾
        }
        else{
            if(p->lchild) q.push(p->lchild);
            if(p->rchild) q.push(p->rchild);
        }
    }
}

你可能感兴趣的:(二叉树)