二叉树

1、创建二叉树

2、先序遍历

3、中序遍历

4、后序遍历

5、二叉树的深度

6、二叉树的镜像

7、二叉树某一路径的和是不是等于给定的数

8、层次遍历二叉树

#include <iostream>
#include <stack>
#include <deque>
#include <malloc.h>
#include <cmath>
#include <vector>
using namespace std;

typedef int Type;
struct BinaryTreeNode
{
    Type value;
    BinaryTreeNode* left;
    BinaryTreeNode* right;
    BinaryTreeNode(Type val) : value(val),left(nullptr),right(nullptr) {}
};

/*
    1、创建二叉树
    2、先序遍历
    3、中序遍历
    4、后序遍历

    5、二叉树的深度
    6、二叉树的镜像
    7、二叉树某一路径的和是不是等于给定的数
    8、层次遍历二叉树
*/
void PreOrder(BinaryTreeNode* head);
void FindPathAvg(BinaryTreeNode* head,int target,vector<int>& path,int currentSum);
void DestoryBinaryNode(BinaryTreeNode* root);
void FindPath(BinaryTreeNode* head,int target);
unsigned int GetLengthOfBinaryTree(BinaryTreeNode* head);
void MirrorOfBinaryTree(BinaryTreeNode* head);
void PrintFromTopToBottom(BinaryTreeNode* head);

/*
    前序遍历二叉树
    递归版 ---->栈
    前序遍历的顺序---> 根节点---左孩子---右孩子
*/
void PreOrder(BinaryTreeNode* head)
{
    if(head==nullptr)
        return;
    cout<<head->value<<"\t";
    PreOrder(head->left);
    PreOrder(head->right);
}
/*
    前序遍历二叉树
    循环版
    1、访问结点p,将结点p入栈
    2、判断p的左孩子,如果为空,则取栈顶元素并出栈操作,并将栈顶元素的右孩子置为当前结点p,循环至1
    3、如果非空,将p的左孩子置为当前结点P
    4、直至P为NULL并且栈为空,则遍历结束
*/
void nPreOrder(BinaryTreeNode* head)
{
    if(head==nullptr)
        return;
    BinaryTreeNode* temp = head;//临时变量,类似游标
    stack<BinaryTreeNode*> result;

    while(temp!=nullptr && !result.empty())
    {
        while(temp!=nullptr)
        {
            cout<<temp->value<<"\t";
            result.push(temp);
            temp = temp->left;
        }
        if(!result.empty())
        {
            temp = result.top();
            result.pop();
            temp = temp->right;
        }
    }
}
/*
    中序遍历二叉树
    递归版
*/
void Inorder(BinaryTreeNode* head)
{
    if(head==nullptr)
        return;
    Inorder(head->left);
    cout<<head->value<<"\t";
    Inorder(head->right);
}
/*
    中序遍历二叉树
    循环版
*/
/*
    后序遍历二叉树
    递归版
*/
void PostOrder(BinaryTreeNode* head)
{
    if(head==nullptr)
        return ;
    PostOrder(head->left);
    PostOrder(head->right);
    cout<<head->value<<"\t";
}
/*
    后序遍历二叉树
    循环版
*/


//释放二叉树
void DestoryBinaryNode(BinaryTreeNode* root)
{
    if(root==nullptr)
        return;

    DestoryBinaryNode(root->left);
    DestoryBinaryNode(root->right);
    free(root);

}

unsigned int GetLengthOfBinaryTree(BinaryTreeNode* head)
{
    if(head==nullptr)
        return 0;
    unsigned int leftlength = GetLengthOfBinaryTree(head->left)+1;
    unsigned int rightlength = GetLengthOfBinaryTree(head->right)+1;

    return max(leftlength,rightlength);
}

void MirrorOfBinaryTree(BinaryTreeNode* head)
{
    if(head==nullptr)
        return ;
    if(head->left==nullptr && head->right==nullptr)
        return ;
    BinaryTreeNode* temp = head->left;
    head->left = head->right;
    head->right = temp;

    if(head->left)
        MirrorOfBinaryTree(head->left);
    if(head->right)
        MirrorOfBinaryTree(head->right);
}

/*
    1、路径是以根结点为起始结点,那么只能选择前序遍历
    2、前序遍历整个二叉树,将改二叉树加入当前路径中,并且累加当前结点的值
    3、如果该节点是叶子节点并且和等于target,则打印改路径
    4、如果改结点不是叶子结点,则继续递归访问他的子节点。
    5、在函数退出之前要在当前路径上删除当前结点并且减去该节点的值。
*/

void PrintVector(vector<int>& data)
{
    if(data.size()<=0)
        return ;
    vector<int>::iterator iter= data.begin();
    for(;iter!=data.end();iter++)
        cout<<*iter<<"\t";
    cout<<endl;
}
void FindPath(BinaryTreeNode* head,int target)
{
    if(head==nullptr)
        return;
    vector<int> path;
    int currentSum = 0;
    FindPathAvg(head,target,path,currentSum);
}
void FindPathAvg(BinaryTreeNode* head,int target,vector<int>& path,int currentSum)
{
    currentSum += head->value;
    path.push_back(head->value);

    //如果是叶节点并且等于目标和,打印路径

    bool isLeaf = head->left==nullptr && head->right==nullptr;

    if(currentSum==target && isLeaf)
    {
        cout<<"A path has Found...The path is :"<<endl;
        PrintVector(path);
    }

    //如果不是叶节点,则遍历他的子节点

    if(head->left!=nullptr)
        FindPathAvg(head->left,target,path,currentSum);
    if(head->right!=nullptr)
        FindPathAvg(head->right,target,path,currentSum);

    //在返回父节点之前,删除当前结点
    path.pop_back();
}

/*
    层次打印二叉树的步骤  利用队列
    1、每次打印一个节点的时候,如果该节点有子节点,则把改结点的子节点放到队列的末尾
    2、然后让结点出队列
    3、重复操作
*/
void PrintFromTopToBottom(BinaryTreeNode* head)
{
    if(head==nullptr)
        return;
    //采用deque ,两边都可以进出
    deque<BinaryTreeNode*> queuenode;

    queuenode.push_back(head);

    while(queuenode.size())
    {
        BinaryTreeNode* temp = queuenode.front();
        queuenode.pop_front();

        cout<<temp->value<<"\t";

        if(temp->left)
            queuenode.push_back(temp->left);
        if(temp->right)
            queuenode.push_back(temp->right);
    }
}
int main()
{
    BinaryTreeNode* node = new BinaryTreeNode(1);
    BinaryTreeNode* node_1 = new BinaryTreeNode(2);
    BinaryTreeNode* node_2 = new BinaryTreeNode(3);

    node->left = node_1;
    node->right = node_2;
    node_1->left = nullptr;
    node_1->right = nullptr;
    node_2->left = nullptr;
    node_2->right = nullptr;
    PreOrder(node);
    cout<<endl;
    Inorder(node);
     cout<<endl;
    PostOrder(node);
    cout<<endl;
    cout<<GetLengthOfBinaryTree(node)<<endl;

    MirrorOfBinaryTree(node);
    Inorder(node);

    FindPath(node,3);

    PrintFromTopToBottom(node);
    DestoryBinaryNode(node);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值