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;        
    }

  

原文地址:https://www.cnblogs.com/leehm/p/12929130.html