2024/2/16

二叉树

概念

树是一个拥有层次关系N(N>0)的有限集合,如果N为0(即层数为0)则为空树,N>0时为非空树

对于非空二叉树,是由一个根节点加两个不相交的子集节点组成,而子节点又可以分别向下延伸出两个不相交的子节点

注:对于根节点有且只有一个,其余都不为根节点,一个节点延伸出的两个节点分别称为左子树和右子树

对于二叉树还有几个概念

  1. 节点的度:一个节点拥有子树的数量
  2. 树的度:树中所有节点的度的最大值
  3. 层:从根节点开始记为1,那么第N个节点处于第N层,其子节点处于N+1层
  4. 树的深度:也称为树的高度,树中所有节点的层次最大值称为树的深度
  5. 分支节点:度不为0的节点
  6. 叶子节点:没有子节点,即度为0的节点

二叉树主要分为满二叉树和完全二叉树

满二叉树:如果一棵二叉树只有度为0的节点和度为2的节点,并且度为0的节点在同一层上,则这棵二叉树为满二叉树

即除了叶子节点,其余分支节点度都为2,都有两个子树

完全二叉树:深度为k,有n个节点的二叉树当且仅当其每一个节点都与深度为k的满二叉树中编号从1到n的节点一一对应时,称为完全二叉树

完全二叉树与满二叉树的区别就是缺少了右边的叶子节点

二叉树的性质

  1. 二叉树的第N层上至多有2N-1(N≥1)个节点
  2. 深度为N的二叉树中至多含有2N-1个节点
  3. 若在任意一棵二叉树中,有N0个叶子节点,有N2个度为2的节点,则必有N0=N2+1 
  4. 具有n个节点的满二叉树深为log2N+1。
  5. 若对一棵有n个节点的完全二叉树进行顺序编号(1≤i≤N),那么,对于编号为i(i≥1)的节点当i=1时,该节点为根节点,当i>1时,该节点的双亲节点的编号为i/2,若2i≤N,则有编号为2i的左节点,否则没有左节点若2i+1≤n,则有编号为2i+1的右节点,否则没有右节点 

二叉树的储存方式

分为链式储存和顺序储存

链式储存

如其名,像链表的储存方式

用两个指针分别指向两个子树,将他们串起来

代码如下

struct tree
{
   int val;
   tree *left;
   tree *right;
};

顺序储存

顺序储存是使用数组来储存

将下标0赋给根节点,那么它的左子树节点下标为1,右子树节点的下标为2

一个节点的下标为i,那么其左子节点下标为2*i+1,右子节点为2*i+2

二叉树的遍历方式

  1. 深度优先遍历:先往深走,遇到叶子节点再往回走。
  2. 广度优先遍历:一层一层的去遍历。

深度遍历又分为先序遍历,中序遍历,后序遍历

  1. 先序遍历:先遍历中间节点,再遍历左右节点
  2. 中序遍历:先遍历左节点,再遍历中右节点
  3. 后序遍历:先遍历左右节点,再遍历中节点

所以先中后指的是中间节点的遍历顺序

代码实现

void find(tree* root)//先序遍历
{
	if(root==NULL)
	   return;
	   cout<<root->val<<" ";//访问根节点
	   find(root->left);//遍历左树
	   find(root->right);//遍历右树
}
void find(tree* root)//中序遍历
{
	if(root==NULL)//空树则返回
	   return;
	   find(root->left);//遍历左树
	   cout<<root->val<<" ";//访问根节点
	   find(root->right);//遍历右树
}
void find(tree* root)//后序遍历
{
	if(root==NULL)
	   return;
	   find(root->left);//遍历左树
	   find(root->right);//遍历右树
	   cout<<root->val<<" ";//访问根节点
}

层序遍历

层次遍历是指从二叉树的根节点开始,按从上到下,从左到右的顺序遍历,类似于数组的顺序遍历

使用队列来实现

void find2(tree* root) {
    if(root==NULL)
	    return;
    queue<tree*>q;
    q.push(root);
    while (!q.empty()) {
        Tree* node=q.front();
        q.pop();
        cout<<node->val<<" "; // 访问当前节点
        if (node->left!=NULL) 
		q.push(node->left);
        if (node>right!=NULL) 
		q.push(node->right);// 将当前节点的左右子节点加入队列
    }
}

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值