c++数据结构与算法之二叉树知识点总结

二叉树关键点

二叉树相关问题的解法主要就是两个
1.使用递归函数来进行深度优先搜索,比如二叉树的前序遍历、中序遍历、后序遍历以及通过二叉树的两个遍历顺序的结果来恢复出二叉树,这些都是通过递归来进行深度优先搜索来实现的。
2.使用队列来进行宽度优先搜索,比如二叉树的层次输出,以及确定二叉树每一层有多少个节点。

构造二叉树(使用链表来表示二叉树)

链表节点

template<class T>
class binaryTreeNode
{
    public:
        T element;
        binaryTreeNode<T>* leftChild;  //左子树
        binaryTreeNode<T>* rightChild; //右子树

        binaryTreeNode()
        {
            leftChild = rightChild = NULL;
        }
        binaryTreeNode(const T& theElement)
        {
            element = theElement;
            leftChild = rightChild = NULL;
        }
        binaryTreeNode(const T& theElement, binaryTreeNode<T>* theLeftChild, binaryTreeNode<T>* theRightChild)
        {
            element = theElement;
            leftChild = theLeftChild;
            rightChild = theRightChild;
        }
};

链表构造

 	binaryTreeNode<int>* root = new binaryTreeNode<int>(1);
    root->leftChild = new binaryTreeNode<int>(2);
    root->rightChild = new binaryTreeNode<int>(3);
    binaryTreeNode<int>* tem_root = root->leftChild;
    tem_root->leftChild = new binaryTreeNode<int>(4);
    tem_root->rightChild = new binaryTreeNode<int>(5);
    tem_root = root->rightChild;
    tem_root->leftChild = new binaryTreeNode<int>(6);
    tem_root->rightChild = new binaryTreeNode<int>(7);

二叉树遍历

深度优先遍历

前序遍历

//前序遍历输出
template<class T>
void preOrder(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        return ;
    }
    if (theRoot != NULL)
    {
        cout << theRoot->element << " ";
        preOrder(theRoot->leftChild);
        preOrder(theRoot->rightChild);
    }
}

中序遍历

//中序遍历输出
template<class T>
void inOrder(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        return ;
    }
    if (theRoot != NULL)
    {
        inOrder(theRoot->leftChild);
        cout << theRoot->element << " ";
        inOrder(theRoot->rightChild);
    }
}

后序遍历

//后序遍历输出
template<class T>
void postOrder(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        return ;
    }
    if (theRoot != NULL)
    {
        postOrder(theRoot->leftChild);
        postOrder(theRoot->rightChild);
        cout << theRoot->element << " ";
    }
}

宽度优先遍历(层次遍历)

//层次遍历,也就是宽度优先搜索
template<class T>
void levelOrder(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        cout << "The tree is empty " << endl;
        return ;
    }
    queue<binaryTreeNode<T>*> tem;
    tem.push(theRoot);
    while(!tem.empty())
    {
        binaryTreeNode<T>* tempRoot = tem.front();
        cout << tempRoot->element << endl;
        if (tempRoot->leftChild != NULL)
        {
            tem.push(tempRoot->leftChild);
        }
        if (tempRoot->rightChild != NULL)
        {
            tem.push(tempRoot->rightChild);
        }
        tem.pop();
    }

}

复制二叉树

前序遍历复制

//前序复制二叉树
template<class T>
void preCopyTree(binaryTreeNode<T>* theRoot, binaryTreeNode<T>* &goalRoot)
{
    if (theRoot == NULL)
    {
        return ;
    }
    if (theRoot != NULL)
    {
        goalRoot = new binaryTreeNode<T>(theRoot->element);
        cout << goalRoot->element << endl;
        preCopyTree(theRoot->leftChild, goalRoot->leftChild);
        preCopyTree(theRoot->rightChild, goalRoot->rightChild);
    }
}

后序遍历复制

//后序复制二叉树
template<class T>
void postCopyTree(binaryTreeNode<T>* theRoot, binaryTreeNode<T>* &goalRoot)
{
    if (theRoot == NULL)
    {
        return ;
    }
    if (theRoot != NULL)
    {
        goalRoot = new binaryTreeNode<T>();
        postCopyTree(theRoot->leftChild, goalRoot->leftChild);
        postCopyTree(theRoot->rightChild, goalRoot->rightChild);
        goalRoot->element = theRoot->element;
        cout << goalRoot->element << endl;
    }
}

二叉树层数与每一层的节点数目

//确定二叉树的哪一层具有最多的节点个数
template<class T>
pair<int, int> maxNode(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        cout << "The tree is empty " << endl;
    }
    map<int, int> level;
    queue<pair<binaryTreeNode<T>* , int>> tem;
    tem.push(make_pair(theRoot, 1));
    while(!tem.empty())
    {
        pair<binaryTreeNode<T>*, int> tem_node = tem.front();
        if(level.find(tem_node.second) == level.end())
        {
            level.insert(make_pair(tem_node.second, 1));
        }
        else
        {
            level[tem_node.second] += 1;
        }
        if (tem_node.first->leftChild != NULL)
        {
            tem.push(make_pair(tem_node.first->leftChild, tem_node.second + 1));
        }
        if(tem_node.first->rightChild != NULL)
        {
            tem.push(make_pair(tem_node.first->leftChild, tem_node.second + 1));
        }
        tem.pop();
    }

    int maxLevel = 0;
    int nums = 0;
    for (auto iter = level.begin(); iter != level.end(); iter++)
    {
        if (iter->second > nums)
        {
            nums = iter->second;
            maxLevel = iter->first;
        }
    }

    return make_pair(maxLevel, nums);

}

二叉树总的节点数目

//二叉树节点数目
template<class T>
int nums(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        return 0;
    }
    int num;
    num = nums(theRoot->leftChild) + nums(theRoot->rightChild) + 1;
    return num;
}

使用前序和中序遍历的结果恢复二叉树

#include <iostream>
#include <vector>
#include <unordered_map>
#include <queue>

#include "binaryTreeNode.h"

using namespace std;

template<class T>
binaryTreeNode<T>* restoreTree(unordered_map<T,int> &hash, vector<T> &pre, int pre_left, int pre_right, int in_left, int in_right);

//层次遍历,也就是宽度优先搜索
template<class T>
void levelOrder(binaryTreeNode<T>* theRoot);

int main()
{
    vector<char> pre = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
    vector<char> in = {'c', 'b', 'd', 'a', 'g', 'f', 'e', 'h'};
    unordered_map<char, int> hash;
    for (int i = 0; i < in.size(); i++)
    {
        hash.insert(make_pair(in[i], i));
    }

    binaryTreeNode<char> *root;
    root = restoreTree(hash, pre, 0, pre.size()-1, 0, in.size()-1);

    levelOrder<char>(root);
    
    return 0;
}

//层次遍历,也就是宽度优先搜索
template<class T>
void levelOrder(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        cout << "The tree is empty " << endl;
        return ;
    }
    queue<binaryTreeNode<T>*> tem;
    tem.push(theRoot);
    while(!tem.empty())
    {
        binaryTreeNode<T>* tempRoot = tem.front();
        cout << tempRoot->element << endl;
        if (tempRoot->leftChild != NULL)
        {
            tem.push(tempRoot->leftChild);
        }
        if (tempRoot->rightChild != NULL)
        {
            tem.push(tempRoot->rightChild);
        }
        tem.pop();
    }

}

template<class T>
binaryTreeNode<T>* restoreTree(unordered_map<T,int> &hash, vector<T> &pre, int pre_left, int pre_right, int in_left, int in_right)
{
    if (pre_left == pre_right || in_left == in_right)
    {
        return new binaryTreeNode<T>(pre[pre_right]);
    }
    if (pre_left > pre_right || in_left > in_right)
    {
        return NULL;
    }
    binaryTreeNode<T>* root;
    binaryTreeNode<T>* root_left, *root_right;
    int center = hash[pre[pre_left]];
    root_left = restoreTree(hash, pre, pre_left + 1, pre_left  + center - in_left, in_left, center - 1);
    root_right = restoreTree(hash, pre, pre_left + center - in_left + 1, pre_right, center + 1, in_right);
    root = new binaryTreeNode<T> (pre[pre_left], root_left, root_right);
}

完整代码

binaryTreeNode.h

#pragma once 

#include <iostream>

using namespace std;

template<class T>
class binaryTreeNode
{
    public:
        T element;
        binaryTreeNode<T>* leftChild;  //左子树
        binaryTreeNode<T>* rightChild; //右子树

        binaryTreeNode()
        {
            leftChild = rightChild = NULL;
        }
        binaryTreeNode(const T& theElement)
        {
            element = theElement;
            leftChild = rightChild = NULL;
        }
        binaryTreeNode(const T& theElement, binaryTreeNode<T>* theLeftChild, binaryTreeNode<T>* theRightChild)
        {
            element = theElement;
            leftChild = theLeftChild;
            rightChild = theRightChild;
        }
};

主文件

#include "binaryTreeNode.h"
#include <iostream>
#include <queue>
#include <utility>
#include <map>

using namespace std;

template<class T>
void deleteTree(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        return ;
    }
    if (theRoot != NULL)
    {
        deleteTree(theRoot->leftChild);
        deleteTree(theRoot->rightChild);
        delete theRoot;
    }
}

//前序遍历输出
template<class T>
void preOrder(binaryTreeNode<T>* theRoot);

//中序遍历输出
template<class T>
void inOrder(binaryTreeNode<T>* theRoot);

//后序遍历输出
template<class T>
void postOrder(binaryTreeNode<T>* theRoot);

//层次遍历,也就是宽度优先搜索
template<class T>
void levelOrder(binaryTreeNode<T>* theRoot);

//复制二叉树
template<class T>
void preCopyTree(binaryTreeNode<T>* theRoot, binaryTreeNode<T>* &goalRoot);

//后序复制二叉树
template<class T>
void postCopyTree(binaryTreeNode<T>* theRoot, binaryTreeNode<T>* &goalRoot);

//二叉树节点个数
template<class T>
int nums(binaryTreeNode<T>* theRoot);

//确定二叉树的哪一层具有最多的节点个数
template<class T>
pair<int, int> maxNode(binaryTreeNode<T>* theRoot);

int main()
{
    binaryTreeNode<int>* root = new binaryTreeNode<int>(1);
    root->leftChild = new binaryTreeNode<int>(2);
    root->rightChild = new binaryTreeNode<int>(3);
    binaryTreeNode<int>* tem_root = root->leftChild;
    tem_root->leftChild = new binaryTreeNode<int>(4);
    tem_root->rightChild = new binaryTreeNode<int>(5);
    tem_root = root->rightChild;
    tem_root->leftChild = new binaryTreeNode<int>(6);
    tem_root->rightChild = new binaryTreeNode<int>(7);

    //前序遍历输出
    cout << "前序遍历输出 : " << endl;
    preOrder(root);
    cout << endl;

    //中序遍历输出
    cout << "中序遍历输出 : " << endl;
    inOrder(root);
    cout << endl;

    //后序遍历输出
    cout << "后序遍历输出 : " << endl;
    postOrder(root);
    cout << endl;

    //层次遍历,也就是宽度优先搜索
    cout << "宽度优先输出 : " << endl;
    levelOrder(root);
    cout << endl;

    cout << "前序复制二叉树 : " << endl;
    binaryTreeNode<int>* preCopyRoot;
    preCopyTree(root, preCopyRoot);
    levelOrder(preCopyRoot);
    cout << endl;

    cout << "后序复制二叉树 : " << endl;
    binaryTreeNode<int>* postCopyRoot;
    postCopyTree(root, postCopyRoot);
    levelOrder(postCopyRoot);
    cout << endl;

    cout << "二叉树节点数目 : " << endl;
    int num = nums(root);
    cout << num << endl;

    cout << "查看哪一层节点数目最多 : " << endl;
    pair<int, int> level = maxNode(root);
    cout << "第" << level.first << "层节点数目最多,有" << level.second << "个节点" << endl;

    
    //释放树
    deleteTree<int>(root);
    deleteTree<int>(preCopyRoot);
    deleteTree<int>(postCopyRoot);


    return 0;
}

//前序遍历输出
template<class T>
void preOrder(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        return ;
    }
    if (theRoot != NULL)
    {
        cout << theRoot->element << " ";
        preOrder(theRoot->leftChild);
        preOrder(theRoot->rightChild);
    }
}

//中序遍历输出
template<class T>
void inOrder(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        return ;
    }
    if (theRoot != NULL)
    {
        inOrder(theRoot->leftChild);
        cout << theRoot->element << " ";
        inOrder(theRoot->rightChild);
    }
}

//后序遍历输出
template<class T>
void postOrder(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        return ;
    }
    if (theRoot != NULL)
    {
        postOrder(theRoot->leftChild);
        postOrder(theRoot->rightChild);
        cout << theRoot->element << " ";
    }
}

//层次遍历,也就是宽度优先搜索
template<class T>
void levelOrder(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        cout << "The tree is empty " << endl;
        return ;
    }
    queue<binaryTreeNode<T>*> tem;
    tem.push(theRoot);
    while(!tem.empty())
    {
        binaryTreeNode<T>* tempRoot = tem.front();
        cout << tempRoot->element << endl;
        if (tempRoot->leftChild != NULL)
        {
            tem.push(tempRoot->leftChild);
        }
        if (tempRoot->rightChild != NULL)
        {
            tem.push(tempRoot->rightChild);
        }
        tem.pop();
    }

}

//前序复制二叉树
template<class T>
void preCopyTree(binaryTreeNode<T>* theRoot, binaryTreeNode<T>* &goalRoot)
{
    if (theRoot == NULL)
    {
        return ;
    }
    if (theRoot != NULL)
    {
        goalRoot = new binaryTreeNode<T>(theRoot->element);
        cout << goalRoot->element << endl;
        preCopyTree(theRoot->leftChild, goalRoot->leftChild);
        preCopyTree(theRoot->rightChild, goalRoot->rightChild);
    }
}

//后序复制二叉树
template<class T>
void postCopyTree(binaryTreeNode<T>* theRoot, binaryTreeNode<T>* &goalRoot)
{
    if (theRoot == NULL)
    {
        return ;
    }
    if (theRoot != NULL)
    {
        goalRoot = new binaryTreeNode<T>();
        postCopyTree(theRoot->leftChild, goalRoot->leftChild);
        postCopyTree(theRoot->rightChild, goalRoot->rightChild);
        goalRoot->element = theRoot->element;
        cout << goalRoot->element << endl;
    }
}

//二叉树节点数目
template<class T>
int nums(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        return 0;
    }
    int num;
    num = nums(theRoot->leftChild) + nums(theRoot->rightChild) + 1;
    return num;
}

//确定二叉树的哪一层具有最多的节点个数
template<class T>
pair<int, int> maxNode(binaryTreeNode<T>* theRoot)
{
    if (theRoot == NULL)
    {
        cout << "The tree is empty " << endl;
    }
    map<int, int> level;
    queue<pair<binaryTreeNode<T>* , int>> tem;
    tem.push(make_pair(theRoot, 1));
    while(!tem.empty())
    {
        pair<binaryTreeNode<T>*, int> tem_node = tem.front();
        if(level.find(tem_node.second) == level.end())
        {
            level.insert(make_pair(tem_node.second, 1));
        }
        else
        {
            level[tem_node.second] += 1;
        }
        if (tem_node.first->leftChild != NULL)
        {
            tem.push(make_pair(tem_node.first->leftChild, tem_node.second + 1));
        }
        if(tem_node.first->rightChild != NULL)
        {
            tem.push(make_pair(tem_node.first->leftChild, tem_node.second + 1));
        }
        tem.pop();
    }

    int maxLevel = 0;
    int nums = 0;
    for (auto iter = level.begin(); iter != level.end(); iter++)
    {
        if (iter->second > nums)
        {
            nums = iter->second;
            maxLevel = iter->first;
        }
    }

    return make_pair(maxLevel, nums);

}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值