zoukankan      html  css  js  c++  java
  • 二叉树的遍历方式(递归和非递归版本)

    二叉树结构体:

    struct BinaryTreeNode 
    {
        int                    m_nValue; 
        BinaryTreeNode*        m_pLeft;  
        BinaryTreeNode*        m_pRight; 
    };

    二叉树创建:

    BinaryTreeNode* CreateBinaryTreeNode(int value)
    {
        BinaryTreeNode* pNode = new BinaryTreeNode();
        pNode->m_nValue = value;
        pNode->m_pLeft = NULL;
        pNode->m_pRight = NULL;
    
        return pNode;
    }

    打印二叉树:

    void PrintTreeNode(BinaryTreeNode* pNode)
    {
        if(pNode != NULL)
        {
            printf("value of this node is: %d
    ", pNode->m_nValue);
    
            if(pNode->m_pLeft != NULL)
                printf("value of its left child is: %d.
    ", pNode->m_pLeft->m_nValue);
            else
                printf("left child is null.
    ");
    
            if(pNode->m_pRight != NULL)
                printf("value of its right child is: %d.
    ", pNode->m_pRight->m_nValue);
            else
                printf("right child is null.
    ");
        }
        else
        {
            printf("this node is null.
    ");
        }
    
        printf("
    ");
    }
    
    void PrintTree(BinaryTreeNode* pRoot)
    {
        PrintTreeNode(pRoot);
    
        if(pRoot != NULL)
        {
            if(pRoot->m_pLeft != NULL)
                PrintTree(pRoot->m_pLeft);
    
            if(pRoot->m_pRight != NULL)
                PrintTree(pRoot->m_pRight);
        }
    }

    销毁二叉树:

    void DestroyTree(BinaryTreeNode* pRoot)
    {
        if(pRoot != NULL)
        {
            BinaryTreeNode* pLeft = pRoot->m_pLeft;
            BinaryTreeNode* pRight = pRoot->m_pRight;
    
            delete pRoot;
            pRoot = NULL;
    
            DestroyTree(pLeft);
            DestroyTree(pRight);
        }
    }

    遍历方式(前序、中序、后序):

    //前序遍历 根节点->左节点->右节点
    void pre_traverse(BinaryTreeNode* pRoot)
    {
        if (pRoot)
        {
            printf(" %d", pRoot->m_nValue);
            if (pRoot->m_pLeft)
                pre_traverse(pRoot->m_pLeft);
            if (pRoot->m_pRight)
                pre_traverse(pRoot->m_pRight);
        }
    }
    
    //前序遍历的非递归实现
    void pre_traverse_stack(BinaryTreeNode* pRoot)
    {
        if (NULL == pRoot)
            return;
    
        stack<BinaryTreeNode*> Bnode;
        BinaryTreeNode* node_pop = NULL; //保存出栈节点
        BinaryTreeNode* pcurrent = pRoot; //访问当前节点
    
        //直至当前节点为空或栈为空时,结束循环
        while (pcurrent||!Bnode.empty())
        {
            //若左子结点非空,则不断输出左子结点数值
            while (pcurrent)
            {
                printf(" %d", pcurrent->m_nValue);
                Bnode.push(pcurrent);
                pcurrent = pcurrent->m_pLeft;
            }
            //记录父节点,顶出父节点,对父节点的右节点进行操作
            if (!Bnode.empty())
            {
                pcurrent = Bnode.top();
                Bnode.pop();
                pcurrent = pcurrent->m_pRight;
            }
        }
    }
    
    //中序遍历 左节点->根节点->右节点
    void mid_traverse(BinaryTreeNode* pRoot)
    {
        if (pRoot)
        {
            if (pRoot->m_pLeft)
                mid_traverse(pRoot->m_pLeft);
            printf(" %d", pRoot->m_nValue);
            if (pRoot->m_pRight)
                mid_traverse(pRoot->m_pRight);
        }
    }
    
    //中序遍历的非递归版本
    void mid_traverse_stack(BinaryTreeNode* pRoot)
    {
        if (NULL == pRoot)
            return;
    
        stack<BinaryTreeNode*> Bnode;
        BinaryTreeNode* pcurrent = pRoot; //访问当前节点
    
        while (pcurrent || !Bnode.empty())
        {
            while (pcurrent)
            {
                Bnode.push(pcurrent);
                pcurrent = pcurrent->m_pLeft;
            }
            if (!Bnode.empty())
            {
                pcurrent = Bnode.top();
                printf(" %d", pcurrent->m_nValue);
                Bnode.pop();
                pcurrent = pcurrent->m_pRight;
            }
        }
    }
    
    //后续遍历 左节点->右节点->根节点
    void beh_traverse(BinaryTreeNode* pRoot)
    {
        if (pRoot)
        {
            if (pRoot->m_pLeft)
                beh_traverse(pRoot->m_pLeft);
            if (pRoot->m_pRight)
                beh_traverse(pRoot->m_pRight);
            printf(" %d", pRoot->m_nValue);
        }
    }
    
    //后序遍历的非递归版本
    void beh_traverse_stack(BinaryTreeNode* pRoot)
    {
        if (NULL == pRoot)
            return;
    
        stack<BinaryTreeNode*> Bnode;
        BinaryTreeNode* pre_node = NULL; //前次访问节点
        BinaryTreeNode* pcurrent = NULL; //访问当前节点
    
        Bnode.push(pRoot);
        while (!Bnode.empty())
        {
            pcurrent = Bnode.top();
            //如果当前节点没有子节点或者子节点已经被访问过,则输出其相应数值
            if ((pcurrent->m_pLeft == NULL&&pcurrent->m_pRight == NULL) ||
                (pre_node != NULL && (pre_node == pcurrent->m_pLeft || pre_node == pcurrent->m_pRight)))
            {
                printf(" %d", pcurrent->m_nValue);
                Bnode.pop();
                pre_node = pcurrent;
            }
            else
            {
                if (pcurrent->m_pRight)
                    Bnode.push(pcurrent->m_pRight);
                if (pcurrent->m_pLeft)
                    Bnode.push(pcurrent->m_pLeft);
            }
        }
    }
  • 相关阅读:
    使用FolderBrowserDialog组件选择文件夹
    使用OpenFileDialog组件打开多个文
    使用OpenFileDialog组件打开对话框
    获取弹出对话框的相关返回值
    PAT 甲级 1139 First Contact (30 分)
    PAT 甲级 1139 First Contact (30 分)
    PAT 甲级 1138 Postorder Traversal (25 分)
    PAT 甲级 1138 Postorder Traversal (25 分)
    PAT 甲级 1137 Final Grading (25 分)
    PAT 甲级 1137 Final Grading (25 分)
  • 原文地址:https://www.cnblogs.com/jason1990/p/4736727.html
Copyright © 2011-2022 走看看