数据结构之二叉树

C++

包含了二叉树创建,增删改查,计算节点个数,二叉树深度,前中后序遍历等实现。

本文二叉树创建的树图为如下

                                              6

                                     2                8

                             1              4

                                       3

6为根节点 8没有子节点,3为4 的左节点

 

控制台输入顺序  6 2 1 0 0 4 3 0 0 0 8 0 0   复制即可

#include<iostream>
using namespace std;

//二叉树:链表
typedef struct TreeNode
{
    //数据域
    int data;

    //指针域
    struct TreeNode * left;
    struct TreeNode * right;
}Node;
//创建二叉树
Node*CreateTree()
{
    Node*p = NULL;
    int num;
    cin >> num;
    if (num==0)
    {
        p = NULL;
    }
    else {
        p = (Node*)malloc(sizeof(Node));    //在堆上给创建一个节点空间
        p->data = num;
        //使用递归创建子树  如果p-》left或者 right为0 则返回空
        p->left = CreateTree();
        p->right = CreateTree();
    }
    return p;    //递归到最后返回二叉树的根节点(第一层节点)
}
//遍历前序
//中序
//后序

//前序 先遍历根节点->左子节点->右子节点
void ForwardSort(Node* root)
{
    if (root)
    {
        cout << root->data << ",";
        ForwardSort(root->left);
        ForwardSort(root->right);
    }
}
//中序 先遍历左子节点->根节点->右子节点
void MiddleSort(Node* root)
{
    if (root)
    {
        MiddleSort(root->left);
        //当程序执行到该行:证明left为NULL
        cout << root->data << ",";
        MiddleSort(root->right);
    }
}
//后序
void BackSort(Node* root)
{
    if (root)
    {
        BackSort(root->left);
        BackSort(root->right);
        cout << root->data << ",";
    }
}

//查找节点(1.递归,2.先把节点放进集合中,再查找)
//递归:前序
//root:在当前二叉树中进行查找
//cc:查找节点data值为cc
Node* SearchNode(Node *root,int cc)
{
    Node*p = root;
    if (p==NULL)
    {
        return NULL;
    }
    if (p->data == cc) {
        return p;
    }
    //根节点对比完成之后开始匹配左子树
    Node* n = SearchNode(p->left, cc);
    if (n==NULL)    //左子树中没有匹配的节点
    {
        return SearchNode(p->right, cc);    //和右子树进行比较
    }
    else {
        return n;    //返回找到的结果
    }
}

//查找指定节点的父节点
//root:当前在二叉树中 进行查找
//cc:查找节点的data值为cc的爸爸节点
Node* SearchParentNode(Node* root, int cc)
{
    Node*n = root;
    if (n==NULL)//当前二叉树没有节点
    {
        return    NULL;
    }
    
    /*if (n->left->data==cc||n->right->data==cc)
    {
        return n;
    }*/
    //修改一下:先判断n->left  n->right 是不是空
    //在进行比对
    if (n->left!=NULL)
    {
        if (n->left->data==cc)
        {
            return n;
        }
    }
    if (n->right != NULL)
    {
        if (n->right->data == cc)
        {
            return n;
        }
    }

    Node *p = SearchParentNode(n->left, cc);
    if (p==NULL)    //左子树没有匹配的节点
    {
        return SearchParentNode(n->right, cc);    //和右子树进行比较
    }
    else {
        return p;
    }

}

//追加:在最底层进行某个节点进行追加
// root:当前二叉树进行追加
//cc:追加新节点的data
//indexCC:追加到该data的节点下
//side:追加成左子树,右子树
void AppendNode(Node*root, int cc,int indexCC,int side)
{
    //根据cc创建一个节点
    Node * newNode = (Node*)malloc(sizeof(Node));
    newNode->data = cc;
    newNode->left = NULL;
    newNode->right = NULL;
    //查找到追加节点的节点
    Node* node = SearchNode(root, indexCC);
    //如果追加的节点有子树:不再进行追加
    if (node == NULL||node->left!=NULL||node->right!=NULL)
    {
        return;
    }
    switch (side)
    {
    case 1:
        node->left= newNode;
        break;
    case 2:
        node->right = newNode;
        break;
    }
}


//插入
//root: 当前二叉树插入
//cc: 追加新节点的data
//indexCC:追加到该data的节点下
//side1: 插入之后让插入的节点为左/右 子树 1:左 2:右
//side2: 插入之后让 原 来 的节点为左/右 子树 1:左 2:右
void InsertNode(Node* root, int cc, int indexCC, int side1, int side2)
{
    if (root==NULL)
    {
        return;
    }
    //创建新的节点
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = cc;
    newNode->left = NULL;
    newNode->right = NULL;

    Node* node = SearchNode(root, indexCC);
    if (node==NULL)//插入的节点不存在
    {
        return;
    }
    //根据side1 把新节点进行设置
    Node * rNode = NULL;
    if (side1==1)
    {
        //新节点插入到左子树中
        rNode = node->left;
        node->left = newNode;
    }
    else {
        //新节点插入到右子树中
        rNode = node->right;
        node->right = newNode;
    }
    //根据side2 把原子节点进行设置
    if (side2==1)
    {
        newNode->left = rNode;
    }
    else {
        newNode->right = rNode;
    }
}
//删除
//在二叉树中删除cc
void DeleteNode(Node* root, int cc) {
    if (root==NULL)
    {
        return;
    }
    Node*p = SearchParentNode(root, cc);
    if (p==NULL)
    {
        root = NULL;;
    }
    if (p->left->data==cc)
    {
        p->left = NULL;
        //把不要的node去free掉
    }
    else {
        p->right = NULL;
    }
}

//计算二叉树节点个数
int CountNode(Node* root) {
    if (root==NULL)
    {
        return 0;
    }
    else {
        //根节点个数+ 左子树节点个数+右子树节点个数
        return 1 + CountNode(root->left) + CountNode(root->right);
    }
}

//计算二叉树深度
int DepthCount(Node* root)
{
    if (root == NULL)
    {
        return 0;
    }
    else {
        //如果左子树的深度大于右子树:我们计算左子树深度,否则计算右子树深度
        return (DepthCount(root->left) > DepthCount(root->right) ? DepthCount(root->left) + 1 : DepthCount(root->right) + 1);
    }
}
int main()
{
    cout << "======创建二叉树=====" << endl;
    //6 2 1 0 0 4 3 0 0 0 8 0 0
    Node* root = CreateTree();    //root指向堆空间(二叉树根节点位置)
    
    cout << "=========前序========" << endl;
    ForwardSort(root);
    cout << endl;
    cout << "=========中序========" << endl;
    MiddleSort(root);
    cout << endl;
    cout << "=========后序========" << endl;
    BackSort(root);
    cout << endl;

    cout << "===============查找节点:查找的节点数据为3(参数)=========" << endl;
    Node* sertchN = SearchNode(root, 3);
    if (sertchN!=NULL)
    {
        cout << sertchN->data << endl;
    }
    else
    {
        cout << "查找的数据在树中不存在" << endl;
    }

    cout << "===============查找节点的父亲=========" << endl;
    Node * searchParentNode = SearchParentNode(root, 3);
    if (searchParentNode!=NULL)
    {
        cout << "Parent=" << searchParentNode->data << endl;
    }
    else {
        cout << "没有" << endl;
    }

    //cout << "======追加二叉树节点=====" << endl;
    //AppendNode(root, 23, 8, 2);


    //cout << "==========删除========" << endl;
    //DeleteNode(root, 2);

    cout << "==========节点个数========" << endl;
    
    cout << CountNode(root)<< endl;

    cout << "==========二叉树深度========" << endl;

    cout << DepthCount(root) << endl;

    //cout << "======后序输出=====" << endl;
    //BackSort(root);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值