二叉树基础

1 二叉树

二叉树(Binary Tree)是一种常见的树状数据结构,它由一组节点组成,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树具有以下特点:

  • 每个节点最多有两个子节点,分别称为左子节点和右子节点。
  • 左子树和右子树也是二叉树,它们的结构与父节点类似。
  • 二叉树的顺序不固定,可以是任意形状。

两种有特殊形式
二叉树有两种形式:满二叉树完全二叉树

  • 满二叉树:如果该二叉树的所有叶子节点都在最后一层,并且结点总数= 2^n -1,n 为层数,则我们称为满二又树。简单点说,满二叉树的每一个分支都是满的。
  • 完全二叉树: 对一个有n个节点的二叉树,按层级顺序编号,则所有节点的编号为从1到n。如果这个树所有节点和同样深度的满二叉树的编号为从1到n的节点位置相同,则这个二叉树为完全二叉树。完全二叉树的条件没有满二叉树那么苛刻: 满二叉树要求所有分支都是满的;而完全二叉树只需保证最后一个节点之前的节点都齐全即可。

2 二叉树节点实现

struct biTree{
    // 数据域
    int val;
    // 指向左孩子的指针域
    biTree * left;
    // 指向右孩子的指针域
    biTree * right;
};

如下图所示:在这里插入图片描述

3 遍历二叉树

二叉树的遍历方式分为三种:前序遍历中序遍历后序遍历
一下是前序遍历的代码:遍历采用递归的方式遍历。在前序遍历中,首先访问根节点,然后按照左子树和右子树的顺序递归地进行前序遍历。

// 线性遍历函数,递归
void preTree(biTree *T){
    if (T == NULL){
        return;
    } else{
        // 先遍历中间节点
        cout << T->val << endl;
        preTree(T->left);
        preTree(T->right);
    }
}

4 存储结构

在这里插入图片描述
在这里我们从下往上开始构建节点,从节点5开始构建。

// 创建节点5
    biTree *node5 = new biTree;
    node5->val = 5;
    node5->left = NULL;
    node5->right = NULL;

    // 创建节点8
    biTree *node8 = new biTree;
    node8->val = 8;
    node8->left = NULL;
    node8->right = NULL;

    // 创建节点3
    biTree *node3 = new biTree;
    node3->val = 3;
    node3->left = NULL;
    node3->right = NULL;
    // 将5,3,8三个连接起来
    node3->left = node5;
    node3->right = node8;

    // 创建2节点
    biTree *node2 = new biTree;
    node2->val = 2;
    node2->left = NULL;
    node2->right = NULL;

    // 创建节点1
    biTree *node1 = new biTree;
    node1->val = 1;
    node1->left = NULL;
    node1->right = NULL;

    // 将左子树,右子树和根节点1连接起来
    node1->left = node3;
    node1->right = node2;

总体代码如下:

#include <iostream>

using namespace std;
struct biTree{
    // 数据域
    int val;
    // 指向左孩子的指针域
    biTree * left;
    // 指向右孩子的指针域
    biTree * right;
};

// 线性遍历函数,递归
void preTree(biTree *T){
    if (T == NULL){
        return;
    } else{
        // 先遍历中间节点
        cout << T->val << endl;
        preTree(T->left);
        preTree(T->right);
    }
}
int main() {
    // 创建节点5
    biTree *node5 = new biTree;
    node5->val = 5;
    node5->left = NULL;
    node5->right = NULL;

    // 创建节点8
    biTree *node8 = new biTree;
    node8->val = 8;
    node8->left = NULL;
    node8->right = NULL;

    // 创建节点3
    biTree *node3 = new biTree;
    node3->val = 3;
    node3->left = NULL;
    node3->right = NULL;
    // 将5,3,8三个连接起来
    node3->left = node5;
    node3->right = node8;

    // 创建二节点
    biTree *node2 = new biTree;
    node2->val = 2;
    node2->left = NULL;
    node2->right = NULL;

    // 创建节点1
    biTree *node1 = new biTree;
    node1->val = 1;
    node1->left = NULL;
    node1->right = NULL;

    // 将左子树,右子树和根节点1连接起来
    node1->left = node3;
    node1->right = node2;

    preTree(node1);
    cout << endl;
    return 0;
}

最终输出为:
在这里插入图片描述

5 创建二叉树函数化

由于以上创建二叉树繁琐,我们将其修改成函数。在函数中,需要使用递归方法创建二叉树。代码如下:

// 先序创建二叉树
void creatpre(biTree *&T){
    int n;
    cout << "请输入当前节点的val值,0代表当前节点为NULL" ;
    cin >>n;
    if ( n == 0){
        T = NULL;
        return;
    } else{
        biTree * node = new biTree;
        node->val = n;
        T = node;
        // 先序遍历创建当前节点的左子树
        creatpre(T->left);
        // 先序遍历创建这个节点的右子树
        creatpre(T->right);
    }
}

步骤:

  • 输入节点值:将输入的值存储在变量n中,
  • 检查是否为NULL节点:如果输入的值为0,那么设置当前节点指针T为NULL,结束递归。
  • 创建非NULL节点:如果输入的值是0,则创建新的biTree节点,并将该节点的值设置为输入值n,然后将节点的指针赋值给T。
  • 递归创建左子树:递归调用 creatpre 函数来创建当前节点的左子树。
  • 递归创建左子树:递归调用 creatpre 函数来创建当前节点的右子树。

改进后的代码如下所示:

#include <iostream>

using namespace std;
struct biTree{
    // 数据域
    int val;
    // 指向左孩子的指针域
    biTree * left;
    // 指向右孩子的指针域
    biTree * right;
};
// 先序创建二叉树
void creatpre(biTree *&T){
    int n;
    cout << "请输入当前节点的val值,0代表当前节点为NULL" ;
    cin >>n;
    if ( n == 0){
        T = NULL;
        return;
    } else{
        biTree * node = new biTree;
        node->val = n;
        T = node;
        // 先序遍历创建当前节点的左子树
        creatpre(T->left);
        // 先序遍历创建这个节点的右子树
        creatpre(T->right);
    }
}
// 线性遍历函数,递归
void preTree(biTree *T){
    if (T == NULL){
        return;
    } else{
        // 先遍历中间节点
        cout << T->val << endl;
        preTree(T->left);
        preTree(T->right);
    }
}
int main() {
	// 创建一个空树
    biTree *T = NULL;
    // 使用先序创建一个二叉树
    creatpre(T);
    // 使用先序遍历这个二叉树
    preTree(T);
    return 0;
}
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值