二叉树的遍历(前/中/后/层,递归&非递归)

二叉树的创建

二叉树的其他面试题

1、前序遍历

递归
  • 如果二叉树为空,则返回空
  • 依次遍历根节点,左子树,右子树
void PreOrder(PBTNode pRoot)
{
    if (NULL == pRoot)
        return;
    else
    {
        printf("%c", pRoot->_data);
        PreOrder(pRoot->pLeft);
        PreOrder(pRoot->pRight);
    }
}
非递归
  • 如果二叉树为空,直接返回
  • 利用栈结构,先将根结点入栈,然后保存根结点,让根结点出栈,然后判断根结点是否有左子树和右子树,有就入栈。依次循环,当栈空时,遍历结束。
  • 别忘记销毁栈
void PreOrderNor(PBTNode pRoot)
{
    PBTNode pCur = NULL;
    Stack s;
    StackInit(&s);

    if (NULL == pRoot)
        return;

    StackPush(&s, pRoot);

    while (!StackEmpty(&s))
    {
        pCur = StackTop(&s);
        StackPop(&s);
        printf("%c", pCur->_data);

        if (pCur->pRight)
            StackPush(&s, pCur->pRight);
        if (pCur->pLeft)
            StackPush(&s, pCur->pLeft);
    }

    StackDestory(&s);
}

2、中序遍历

递归
  • 如果二叉树为空,则返回空
  • 依次遍历左子树,根节点、右子树
void InOrder(PBTNode pRoot)
{
    if (NULL == pRoot)
        return;
    else
    {
        InOrder(pRoot->pLeft);
        printf("%c", pRoot->_data);
        InOrder(pRoot->pRight);
    }
}
非递归
  • 如果二叉树为空,则返回;
  • 访问循环二叉树的左子树,如果存在,则入栈;不存在,打印根节点,出栈该节点,并访问该节点的右子树
void InOrderNor(PBTNode pRoot)
{
    Stack s;
    PBTNode pCur = NULL;
    if (NULL == pRoot)
        return;

    StackInit(&s);
    pCur = pRoot;

    while (!StackEmpty(&s)||pCur)
    {
        while (pCur)
        {
            StackPush(&s, pCur);
            pCur = pCur->pLeft;
        }

        pCur = StackTop(&s);
        printf("%c", pCur->_data);
        StackPop(&s);

        pCur = pCur->pRight;
    }
}

3、后序遍历

递归
  • 如果二叉树为空,则返回空
  • 依次遍历左子树、右子树、根节点
void PostOrder(PBTNode pRoot)
{
    if (NULL == pRoot)
        return;
    else
    {
        PostOrder(pRoot->pLeft);
        PostOrder(pRoot->pRight);
        printf("%c", pRoot->_data);
    }
}
非递归
  • 如果二叉树为空,则返回
  • 判断该节点是否有左右子树,如果没有,则打印。并出栈该节点
  • 如果一个树有右子树,则保存它的右子树,第二次判断是否该节点已经访问过,如果访问过则不在访问
void PostOrderNor(PBTNode pRoot)
{   
    Stack s;
    PBTNode pCur = NULL;
    PBTNode pPre = NULL;
    PBTNode pTop = NULL;

    if (NULL == pRoot)
        return;
    StackInit(&s);
    pCur = pRoot;
    while (!StackEmpty(&s) || pCur)
    {
        while (pCur)
        {
            StackPush(&s, pCur);
            pCur = pCur->pLeft;

        }

        pTop = StackTop(&s);
        if (NULL == pTop->pRight || pPre == pTop->pRight)
        {
            printf("%c", pTop->_data);
            pPre = pTop;
            StackPop(&s);
        }
        else
        {
            pCur = pTop->pRight;
        }
    }
}

4、层序遍历

  • 如果二叉树为空,则返回
  • 将二叉树的根结点的指针入队列
  • 若队列非空,将队列中的队头元素出队列,然后将该队头元素的左孩子指针(若存在)入队列,接着将队头元素的右孩子指针(若存在)入队列,重复此过程,直到队列中没有元素为止
void LevelOrder(PBTNode pRoot)
{
    Queue q;
    PBTNode pCur = NULL;

    if (NULL == pRoot)
        return;

    QueueInit(&q);
    QueuePush(&q, pRoot);

    while (!QueueEmpty(&q))
    {
        pCur = QueueFrontData(&q);
        QueuePop(&q);
        printf("%c", pCur->_data);

        if (pCur->pLeft)
            QueuePush(&q, pCur->pLeft);
        if (pCur->pRight)
            QueuePush(&q, pCur->pRight);
    }

    QueueDestory(&q);
}

猜你喜欢

转载自blog.csdn.net/LYJwonderful/article/details/80252401