二叉树遍历

深度遍历:

递归版:递归方法一定要记得加结束条件。三种遍历只是输出语句位置不同。

前序:

void PreOrderTraversal(Tree* tmp)
{
    if(tmp == NULL) return;
    printf("%d\n",tmp->val);
    PreOrderTraversal(tmp->pleft);
    PreOrderTraversal(tmp->pright);
}

中序:

void InOrderTraversal(Tree* tmp)
{
        
    if(tmp == NULL) return;
    InOrderTraversal(tmp->pleft);
    printf("%d\n",tmp->val);
    InOrderTraversal(tmp->pright);
}

后序:

void LastOrderTraversal(Tree* tmp)
{
    if(tmp == NULL) return;
    LastOrderTraversal(tmp->pleft);
    LastOrderTraversal(tmp->pright);
    printf("%d\n",tmp->val);    
}

非递归版:辅助栈完成,后序遍历和前序,中序有所差别,因为后序树最后输出根,找到右孩子,还要保留根,不弹出。

前序:

void UnRecPreTraversal(Tree* tree)
{
    if(tree == NULL) return;
    //申请辅助栈
    Stack* mystack = s_Init();
    while(1)
    {
        while(tree)
        {   
            //打印
            printf("%d ",tree->val);
            //入栈
            s_Push(mystack,tree);
            //向左走
            tree = tree->pleft;
        }
        //弹出
        tree= s_Pop(mystack);
        //栈空结束
        if(tree == NULL ) break;
        tree = tree->pright;
    }    
    s_Destroy(&mystack);
}

中序:与前序遍历只改变了输出语句的位置

void UnRecInTraversal(Tree* tree)
{
    if(tree == NULL) return;
    Stack* mystack = s_Init(); 
    while(1)
    {
        while(tree)
        {
            s_Push(mystack,tree);
            tree = tree->pleft;
        }
        tree= s_Pop(mystack);
        if(tree == NULL) break;
        printf("%d ",tree->val);
        tree = tree->pright;
    }    
    s_Destroy(&mystack);
}

后序:先输出根的右孩子,再输出根,所以不能先将根弹出,当右孩子处理完毕或者右孩子为空时,再弹出打印。作为父亲节点,打印的前一个节点一定是它的右孩子

void UnRecLastTraversal(Tree* tree)
{
    if(tree == NULL) return;
    //辅助栈
    Stack* mystack = s_Init(); 
    Tree* bj = NULL;
    while(1)
    {
        while(tree)
        {
            //入栈向左走
            s_Push(mystack,tree);
            tree = tree->pleft;
        }
        if(mystack->pHead == NULL) break;
        //当栈顶元素没有右孩子,或者右孩子被标记(处理过),弹出此根节点
        if(mystack->pHead->val->pright == NULL || mystack->pHead->val->pright == bj)
        {    
            //弹出 打印 标记
            bj = s_Pop(mystack);
            printf("%d ",bj->val);
        }
        else //处理右孩子
        {
            tree = mystack->pHead->val->pright;    
        }
    }    
    s_Destroy(&mystack);
}

层序遍历:辅助队列,将节点先压入队列,每次取出先输出,然后查看是否有左右节点再压入队列

void LevelTraversal(BinaryTree *pTree)
{
    if(pTree == NULL)return;

    //申请辅助队列
    Queue *pQueue = Init();//根入队
    q_Push(pQueue,pTree);

    while(!q_IsEmpty(pQueue))
    {
        //弹出
        pTree = q_Pop(pQueue);

        //打印
        printf("%d ",pTree->nValue);

        //非空左右入队
        if(pTree->pLeft)  q_Push(pQueue,pTree->pLeft);
        if(pTree->pRight)  q_Push(pQueue,pTree->pRight);
    }
}

 

posted @ 2018-05-12 12:20  Lune-Qiu  阅读(167)  评论(0编辑  收藏  举报