二叉树的遍历

二叉树节点的定义:
 struct treeT
{
    ElemType key;
    struct treeT* left;
    struct treeT* right;
}*pTreeT

递归实现:

先序遍历:

void BT_PreOrder(pTreeT root)
{
    if (NULL != root)
    {
        visit(root);
        BT_PreOrder(root->left);
        BT_PreOrder(root->right);
    }    
}

中序遍历:

void BT_InOrder(pTreeT root)
{
    if (NULL != root)
    {
        BT_InOrder(root->left);
        visit(root);
        BT_InOrder(root->right);
    }
}

后序遍历:

void BT_PostOrder(pTreeT root)
{
    if (NULL != root)
    {
        BT_PostOrder(root->left);
        BT_PostOrder(root->right);
        visit(root);    
    }
}


非递归实现:

在非递归实现中,都是用到栈结果来保存。

void BT_PreOrderNoRec(pTreeT root)
{
    stack<treeT *> s;

    while ((NULL != root) || !s.empty())
    {
        if (NULL != root)
        {
            visit(root);
            s.push(root);
            root = root->left;
        }
        else
        {
            root = s.top();
            s.pop();
            root = root->right;
        }
    }
}



void BT_InOrderNoRec(pTreeT root)
{
    stack<treeT *> s;
    while ((NULL != root) || !s.empty())
    {
        if (NULL != root)
        {
            s.push(root);
            root = root->left;
        }
        else
        {
            root = s.top();
            visit(root);
            s.pop();
            root = root->right;
        }
    }
}

后序遍历的非递归实现稍微需要仔细推敲一下,但是理解了也很简单。

基本思想是:先找到最左边的叶子并把路上遇到的节点依次压栈,然后弹出栈顶的元素(该元素为最左边的叶子),并判断(1)它有没有右节点;(2)右节点是否被访问过。如果(1)为有右节点同时(2)为没有访问过,则先压入刚才弹出的元素,然后再压入它的右子树。否则,就访问该节点,并设置pre为该节点。

void BT_PostOrderNoRec(pTreeT root)
{
    stack<treeT *> s;
    pTreeT pre=NULL;//pre记录的是前一个被访问的节点

    while ((NULL != root) || !s.empty())
    {
        if (NULL != root)
        {
            s.push(root);
            root = root->left;
        }
        else
        {
            root = s.top();
            if (root->right!=NULL && pre!=root->right)
            {
                root=root->right;
            }
            else
            {
                root=pre=s.top();
                visit(root);
                s.pop();
                root=NULL;
            }
        }
    }
}


二叉树的层序遍历使用队列实现:

void BT_LevelOrder(pTreeT root)
{
    queue<treeT *> q;
    treeT *treePtr;

    assert( NULL != root ); 

    q.push(root);

    while (!q.empty())
    {
        treePtr = q.front();
        q.pop();
        visit(treePtr);

        if (NULL != treePtr->left)
        {
            q.push(treePtr->left);    
        }
        if (NULL != treePtr->right)
        {
            q.push(treePtr->right);
        }    
            
    }
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值