• 二叉树的遍历方式(递归和非递归版本)


    二叉树结构体:

    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);
            }
        }
    }
  • 相关阅读:
    CGFloat,CGPoint,CGSize,CGRect
    对discuz的代码分析学习(三)mysql驱动
    对discuz的代码分析学习(二)首页文件
    对discuz的代码分析学习(一)目录结构
    获取HTML DOM
    html中如何使用特殊字体
    如何让元素自动居中
    前端分页
    页面缩放scale
    控制台获取当前年的月份列表
  • 原文地址:https://www.cnblogs.com/jason1990/p/4736727.html
Copyright © 2020-2023  润新知