• C++11 binary Tree



    二叉树类: BinaryTree
    树节点类: Node

       包含一些常用的操作:

      1. 创建二叉树: 将vector数据构建成二叉树结构  A:按节点左右加入  B:按层级一层层构建

           2. 二叉树反转

           3. 二叉树是否对称,即左右是否成镜像

           4. 前序遍历

           5. 中序遍历

           6. 后续遍历

           7. 层级遍历

    
    

    #include <string>
    #include <memory>
    #include <vector>
    #include <iostream>
    #include <sstream>
    #include <queue>


    ///////////////
    class Node { public: Node(int data, std::string strData = "") :m_nData{ data } ,m_string{ strData } ,m_pLeftChild{ nullptr } ,m_pRightChild{ nullptr }{} virtual ~Node(){} public: int getData() { return m_nData; } void setData(int data) { m_nData = data; } std::string getString() { return m_string;} void setString(std::string strData) { m_string = strData; } public: bool operator < (Node node) { if (m_nData < node.getData()) return true; else return false; } public: std::shared_ptr<Node> m_pLeftChild; std::shared_ptr<Node> m_pRightChild; //value private: int m_nData; std::string m_string; }; ////////////////////////////////////////////////////// class BinaryTree { public: BinaryTree(){} virtual ~BinaryTree(){} public: //创建二叉树: 通过比较节点大小方式插入,小于往左,大于往右 int create(std::vector<int> vecData) { for (auto itor : vecData) { std::ostringstream ostrStream; ostrStream << "" << itor << std::endl; std::shared_ptr<Node> pNode = std::make_shared<Node>(itor, ostrStream.str()); //通过返回值返回root,使用引用传入参数,修改root也是一种方式。 addNode(m_pRoot, pNode); } return 0; } //创建二叉树:按照层次由root节点开始,一层层创建,借用queue实现 int createByLevel(std::vector<int> vecData) { if (vecData.empty()) { return -1; } std::queue<std::shared_ptr<Node>> que; std::vector<int>::iterator itor = vecData.begin(); if (m_pRoot == nullptr) { std::ostringstream ostrStream; ostrStream << *itor << std::endl; m_pRoot = std::make_shared<Node>(*itor, ostrStream.str()); itor++; } que.push(m_pRoot); while (itor != vecData.end()) { std::shared_ptr<Node> pNode = que.front(); //add node std::ostringstream ostrStream; ostrStream << *itor << std::endl; std::shared_ptr<Node> pNodeAdded = std::make_shared<Node>(*itor, ostrStream.str()); if (pNode->m_pLeftChild == nullptr) { pNode->m_pLeftChild = pNodeAdded; } else if (pNode->m_pRightChild == nullptr) { pNode->m_pRightChild = pNodeAdded; } //左右构建完成,出列,然后分别入列左右,分别再构建 if (pNode->m_pLeftChild != nullptr && pNode->m_pRightChild != nullptr) { que.pop(); que.push(pNode->m_pLeftChild); que.push(pNode->m_pRightChild); } itor++; } return 0; } //二叉树反转 int reversal(std::shared_ptr<Node> pTreeNodeStart) { if (pTreeNodeStart == nullptr) return 0; //reversal left tree reversal(pTreeNodeStart->m_pLeftChild); //reversal right tree reversal(pTreeNodeStart->m_pRightChild); //swap left child and right child std::swap(pTreeNodeStart->m_pLeftChild, pTreeNodeStart->m_pRightChild); return 0; } //判断二叉树是否对称 bool isMirror() { if (m_pRoot == nullptr) return true; else { //检查左右子树是否是镜像 return checkMirror(m_pRoot->m_pLeftChild,m_pRoot->m_pRightChild); } } bool checkMirror(std::shared_ptr<Node> leftChild, std::shared_ptr<Node> rightChild) { //两边都是null,ture if (leftChild == nullptr && rightChild == nullptr) return true; //两边只有一边是null,false if(leftChild == nullptr || rightChild == nullptr) return false; //两边都不是null if (leftChild->getData() != rightChild->getData()) return false; //检查左子的左边和右子的右边 bool ret1 = checkMirror(leftChild->m_pLeftChild, rightChild->m_pRightChild); //检查左子的右边和右子的左边 bool ret2 = checkMirror(leftChild->m_pRightChild, rightChild->m_pLeftChild); //同时都满足,才是ture return (ret1 && ret2); } //前序遍历: root->left->right int preorderDump(std::vector<int> &vecData) { return preorderTraversal(m_pRoot,vecData); } //中序遍历: left->root->right int inorderDump(std::vector<int> &vecData) { return inorderTraversal(m_pRoot, vecData); } //后序遍历: left->right->root int postorderDump(std::vector<int> &vecData) { return postorderTraversal(m_pRoot, vecData); } //按层遍历: root层--->叶子节点层 int levelDump(std::vector<int> &vecData) { return levelTraversal(m_pRoot, vecData); } std::shared_ptr<Node> root() { return m_pRoot; } private: //节点加入左子,还是右子的条件: 比较大小 //传入引用,改变pTreeNodeStartAdd的值 int addNode(std::shared_ptr<Node> &pTreeNodeStartAdd, std::shared_ptr<Node> pNode) { if (pTreeNodeStartAdd == nullptr) { pTreeNodeStartAdd = pNode; return 0; } //小于往左子树加入 if (pNode->getData() < pTreeNodeStartAdd->getData()) { addNode(pTreeNodeStartAdd->m_pLeftChild, pNode); } else //大于等于往右 { addNode(pTreeNodeStartAdd->m_pRightChild, pNode); } return 0; } //前序遍历,节点放入vector int preorderTraversal(std::shared_ptr<Node> pTreeNodeStart, std::vector<int> &vecData) { if (pTreeNodeStart == nullptr) { return 0; } //root vecData.push_back(pTreeNodeStart->getData()); //left preorderTraversal(pTreeNodeStart->m_pLeftChild, vecData); //right preorderTraversal(pTreeNodeStart->m_pRightChild, vecData); return 0; } //中序遍历,节点放入vector int inorderTraversal(std::shared_ptr<Node> pTreeNodeStart, std::vector<int> &vecData) { if (pTreeNodeStart == nullptr) { return 0; } //left inorderTraversal(pTreeNodeStart->m_pLeftChild, vecData); //root vecData.push_back(pTreeNodeStart->getData()); //right inorderTraversal(pTreeNodeStart->m_pRightChild, vecData); return 0; } //后续遍历节点放入vector int postorderTraversal(std::shared_ptr<Node> pTreeNodeStart, std::vector<int> &vecData) { if (pTreeNodeStart == nullptr) { return 0; } //left postorderTraversal(pTreeNodeStart->m_pLeftChild, vecData); //right postorderTraversal(pTreeNodeStart->m_pRightChild, vecData); //root vecData.push_back(pTreeNodeStart->getData()); return 0; } //借用一个临时队列来实现 //从root开始,加入队列,先访问后,将root的左右节点分别加入队列, //然后从队列取出左节点,访问后,将左节点的左右子节点入队列,再取出之前入列的右节点,访问后,将右节点的左右字节点入队列 //此时队列里面就会有root左子的左右子节点,右子的左右子节点 //按照此循环下去,直到队列里面没有元素,即到叶子节点为止了。 int levelTraversal(std::shared_ptr<Node> pTreeNodeStart, std::vector<int> &vecData) { if (pTreeNodeStart == nullptr) { return 0; } std::queue<std::shared_ptr<Node>> que; que.push(pTreeNodeStart); while (!que.empty()) { std::shared_ptr<Node> pNode = que.front(); que.pop(); //访问元素 vecData.push_back(pNode->getData()); //左子节点入队列 if (pNode->m_pLeftChild != nullptr) que.push(pNode->m_pLeftChild); //右子节点入队列 if(pNode->m_pRightChild != nullptr) que.push(pNode->m_pRightChild); } return 0; } private: std::shared_ptr<Node> m_pRoot; };

    测试代码:

    int main()
    {
        //创建树,非镜像二叉树,先查看各种遍历结果,反转后,再查看
        std::vector<int> vecData = {100,80,120,70,90,110,130,65,75,85,95,105,115,125,135};
        for (auto index : vecData)
        {
            std::cout << index << ',';
        }
        std::cout << std::endl;
        //创建树
        BinaryTree tree;
        tree.create(vecData);
        //是否镜像
        std::cout << "Tree is mirror: " << tree.isMirror() << std::endl;
        //前序遍历
        std::vector<int> vecDumpData;
        tree.preorderDump(vecDumpData);
    
        std::cout << "preorder traversal: ";
        for (auto index : vecDumpData)
        {
            std::cout << index << ',';
        }
        std::cout << std::endl;
        //中序遍历
        vecDumpData.clear();
        tree.inorderDump(vecDumpData);
        std::cout << "inorder traversal: ";
        for (auto index : vecDumpData)
        {
            std::cout << index << ',';
        }
        std::cout << std::endl;
        //后续遍历
        vecDumpData.clear();
        tree.postorderDump(vecDumpData);
        std::cout << "postorder traversal: ";
        for (auto index : vecDumpData)
        {
            std::cout << index << ',';
        }
        std::cout << std::endl;
        //层级遍历
        vecDumpData.clear();
        tree.levelDump(vecDumpData);
        std::cout << "level traversal: ";
        for (auto index : vecDumpData)
        {
            std::cout << index << ',';
        }
        std::cout << std::endl;
        //二叉树反转
        std::cout << "##############after reversal################ " << std::endl;
        tree.reversal(tree.root());
        
        //反转后,前序遍历
        vecDumpData.clear();
        tree.preorderDump(vecDumpData);
    
        std::cout << "preorder traversal: ";
        for (auto index : vecDumpData)
        {
            std::cout << index << ',';
        }
        std::cout << std::endl;
        //中序续遍历
        vecDumpData.clear();
        tree.inorderDump(vecDumpData);
        std::cout << "inorder traversal: ";
        for (auto index : vecDumpData)
        {
            std::cout << index << ',';
        }
        std::cout << std::endl;
        //后续遍历
        vecDumpData.clear();
        tree.postorderDump(vecDumpData);
        std::cout << "postorder traversal: ";
        for (auto index : vecDumpData)
        {
            std::cout << index << ',';
        }
        std::cout << std::endl;
        //层级遍历
        vecDumpData.clear();
        tree.levelDump(vecDumpData);
        std::cout << "level traversal: ";
        for (auto index : vecDumpData)
        {
            std::cout << index << ',';
        }
        std::cout << std::endl;
    
    
    
        //按照层级创建镜像二叉树,反转后,各个遍历输出应该一致
        std::cout << "##############tree2 createByLevel################ " << std::endl;
        BinaryTree tree2;
        tree2.createByLevel(vecData);
        //层级遍历,查看是否成功
        vecDumpData.clear();
        tree2.levelDump(vecDumpData);
        std::cout << "tree2 level traversal: ";
        for (auto index : vecDumpData)
        {
            std::cout << index << ',';
        }
        std::cout << std::endl;
    
        //创建树,是否镜像判断
        std::cout << "#######mirror binary tree####" << std::endl;
        std::vector<int> vecData2 = {1,2,2,3,4,4,3,5,6,7,8,8,7,6,5};
        for (auto index : vecData2)
        {
            std::cout << index << ",";
        }
        std::cout << std::endl;
    
        BinaryTree mirrorTree;
        mirrorTree.createByLevel(vecData2);
        std::cout << "Tree is mirror: " << mirrorTree.isMirror() << std::endl;
        //层级遍历,查看结果
        vecData2.clear();
        mirrorTree.levelDump(vecData2);
        std::cout << "mirrorTree level traversal: ";
        for (auto index : vecData2)
        {
            std::cout << index << ",";
        }
        std::cout << std::endl;
        //前序遍历
        vecData2.clear();
        mirrorTree.preorderDump(vecData2);
        std::cout << "mirrorTree preorder traversal: ";
        for (auto index : vecData2)
        {
            std::cout << index << ",";
        }
        std::cout << std::endl;
        //中序遍历
        vecData2.clear();
        mirrorTree.inorderDump(vecData2);
        std::cout << "mirrorTree inorder traversal: ";
        for (auto index : vecData2)
        {
            std::cout << index << ",";
        }
        std::cout << std::endl;
        //后序遍历
        vecData2.clear();
        mirrorTree.postorderDump(vecData2);
        std::cout << "mirrorTree postorder traversal: ";
        for (auto index : vecData2)
        {
            std::cout << index << ",";
        }
        std::cout << std::endl;
        //镜像二叉树反转后查看结果
        std::cout << "mirror binary tree reversal==============" << std::endl;
        mirrorTree.reversal(mirrorTree.root());
        vecData2.clear();
        mirrorTree.levelDump(vecData2);
        std::cout << "mirrorTree level traversal: ";
        for (auto index : vecData2)
        {
            std::cout << index << ",";
        }
        std::cout << std::endl;
    
        vecData2.clear();
        mirrorTree.preorderDump(vecData2);
        std::cout << "mirrorTree preorder traversal: ";
        for (auto index : vecData2)
        {
            std::cout << index << ",";
        }
        std::cout << std::endl;
    
        vecData2.clear();
        mirrorTree.inorderDump(vecData2);
        std::cout << "mirrorTree inorder traversal: ";
        for (auto index : vecData2)
        {
            std::cout << index << ",";
        }
        std::cout << std::endl;
    
        vecData2.clear();
        mirrorTree.postorderDump(vecData2);
        std::cout << "mirrorTree postorder traversal: ";
        for (auto index : vecData2)
        {
            std::cout << index << ",";
        }
        std::cout << std::endl;
    
        return 0;
    }
    View Code

    输出:

    层序遍历,返回二维矩阵leetcode

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<vector<int>> levelOrder(TreeNode* root) {
           vector <vector <int>> ret;
            if(root == nullptr)
                return ret;
            
            std::queue<TreeNode*> que;
            que.push(root);
    
            while(!que.empty())
            {
                int size = que.size();
                //each level
                vector<int> row;
                for(int i = 0; i < size; i++)
                {
                    TreeNode *pNode = que.front();
                    row.push_back(pNode->val);
    
                    if(pNode->left != nullptr)
                        que.push(pNode->left);
                    if(pNode->right != nullptr)
                        que.push(pNode->right);
    
                    que.pop();
                }
                //
                ret.push_back(row);
            }
    
            return ret;
        }
    };

    非递归的前序和中序

    vector<int> inorderTraversal(TreeNode* root) {
            stack<TreeNode*> stackNode;
            vector<int> vectorNode;
            TreeNode* p = root;
            while(p != nullptr || !stackNode.empty())
            {
                while(p != nullptr){
                    //先访问左边,再出栈访问中和右,前序
                    //vectorNode.push_back(p->val);
                    ////
                    stackNode.push(p);
                    p = p->left;
                }
                p = stackNode.top();
                //最左边先出栈访问,中序遍历
                vectorNode.push_back(p->val);
                p = p->right;
                stackNode.pop();
            }
            return vectorNode;        
        }
    

      

  • 相关阅读:
    Java中数据类型的分类
    PL/SQL Developer工具
    Oracle数据库SQL语句的分类
    Oracle数据库控制台常用命令
    关于C#中泛型类型参数约束(where T : class)
    C#动态操作DataTable(新增行、列、查询行、列等)
    ADO.NET 全面整理
    区块链入门教程
    排序算法汇总
    常用SQL
  • 原文地址:https://www.cnblogs.com/leehm/p/12929130.html
Copyright © 2020-2023  润新知