【数据结构】第5章 树和二叉树 二叉树

【二叉树的啦啦啦啦】


1、二叉树的类型

在这里插入图片描述
满二叉树:深度为 k 且含有 2 ^ k - 1 个结点的二叉树。每一层上的结点数都是最大结点数,即每一层l的结点数都具有最大值 2 ^ (i - 1) 可以对满二叉树的结点进行连续编号, 约定编号从根结点起, 自上而下, 自左至右
完全二叉树:深度为 k 的, 有n个结点的二叉树, 其每一个结点都与深度为 k 的满二叉树中编号从 1 至 n 的结点一一对应。(1) 叶子结点只可能在层次最大的两层上出现; (2) 对任一结点, 若其右分支下的子孙的最大层次为 l ,则其左分支下的子孙的最大层次必为l或 l + 1

2、二叉树的性质

性质1:在二叉树的第 i 层上至多有 2 ^ (i - 1) 个结点(i >= 1)
性质2:深度为 k 的二叉树至多有 2 ^ k - 1个结点 (k >= 1)
性质3:对任何一棵二叉树T,,如果其终端结点数为n0,度为2的结点数为n2,则n0 = n2 + 1

证明:
先看结点数。因为二叉树中所有结点的度均小于或等于2, 所以其结点总数为 n = n0 + n1 + n2 ①
再看分支数。除了根结点外,其余结点都有一个分支进入,设B为分支总数,则 n = B + 1。这些分支是由度为 1 或 2 的结点射出的,所以又有 B = n1 + 2n2 。于是得 n = n1 + 2n2 + 1 ②
联立得 n0 = n2 + 1
在这里插入图片描述 在这里插入图片描述在这里插入图片描述在这里插入图片描述

3、二叉树的遍历

假如从 L、D、R分别表示遍历左子树、访 问根结点和遍历右子树,则可有DLR、LDR、LRD、DRL、RDL、RLD这6种遍历二叉树的方案。 若限定先左后右,则只有前3种情况,分别称之为先(根) 序遍历、中(根) 序遍历和后(根) 序遍历。还有按层次遍历二叉树的方式,这种方式按照 “从上到下,从左到右" 的顺序遍历二叉树,即先遍历二叉树第一层的结点,然后是第二层的结点,直到最底层的结点,对每一层的遍历按照从左到右的次序进行。
在这里插入图片描述
在这里插入图片描述
中序遍历非递归(栈)示意图
在这里插入图片描述
由二叉树的先序序列和中序序列,或由其后序序列和中序序列均能唯一地确定一棵二叉树。
例:已知一棵二叉树的中序序列和后序序列分别是 BDCEAFHG 和 DECBHGFA, 请画出这棵二叉树。
在这里插入图片描述
先序遍历的顺序建立二叉链表,对图5.10(b)所示的二叉树,读入字符的顺序为: ABC##DE#G##F### (其中#表示 空树),可建立相应的二叉链表。
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef int Status;
typedef char TElemType;
#define OVERFLOW -1
#define ERROR 0
#define OK 1

-----二叉树的顺序储存表示-----
//#define MAXTSIZE 100                    //二叉树的最大结点数
//typedef TElemType SqBiTree[MAXTSIZE];   //0号单元存储根结点
//SqBiTree bt;

//-----二叉树的二叉链式存储表示-----
typedef struct BiTNode
{
    TElemType data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

BiTree T;

// //1
// InitBiTree(&T)
// //2
// DestroyBiTree(&T)

//3、先序遍历的顺序建立二叉链表 
void CreateBiTree(BiTree &T)
{//按先序次序输入二叉树中结点的值( 一个字符), 创建二叉链表表示的二叉树T
    TElemType ch;
    cin>>ch;
    if(ch == '#')                    //递归结束, 建空树
        T = NULL;
    else                            //递归创建二叉树
    {
        T = new BiTNode;            //生成根结点
        T->data = ch;               //根结点数据域置为 ch
        CreateBiTree(T->lchild);    //递归创建左子树
        CreateBiTree(T->rchild);    //递归创建右子树
    }
}

// //4
// ClearBiTree(&T)
// //5
// BiTreeEmpty(T)
// //6
// BiTreeDepth(T)
// //7
// Root(T)
// //8
// Value(T, e)
// //9
// Assign(T, e, value)
// //10
// Parent(T, e)
// //11
// LeftChild(T, e)
// //12 
// RightChild(T, e)
// //13
// LeftSibling(T, e)
// //14
// RightSibling(T, e)
// //15
// InsertChild(&T, p, LR, c)
// //16
// DeleteChild(&T, p, LR)

//17、先序遍历二叉树
void PreOrderTraverse(BiTree T)
{//先序遍历二叉树T的递归算法
    if(T)                               //若二叉树非空 
    {
        cout<<T->data;                  //访问根结点 
        PreOrderTraverse(T->lchild);     //中序遍历左子树 
        PreOrderTraverse(T->rchild);     //中序遍历右子树
    }
}

//18、中序遍历二叉树
void InOrderTraverse(BiTree T)
{//中序遍历二叉树T的递归算法
    if(T)                               //若二叉树非空 
    {
        InOrderTraverse(T->lchild);     //中序遍历左子树 
        cout<<T->data;                  //访问根结点 
        InOrderTraverse(T->rchild);     //中序遍历右子树
    }
}

// //18、中序遍历二叉树
// void InOrderTraverse(BiTree T)
// {//中序遍历二叉树T的非递归算法
//     InitStack(S);
//     BiTNode *p = T;
//     BiTNode *q = new BiTNode;
//     while(p || !StackEmpty(S))
//     {
//         if(p)                   //p非空
//         {
//             Push(S, p);         //根指针进栈
//             p = p->lchild;      //遍历左子树
//         }
//         else                    //p为空
//         {
//             Pop(S, q);          //退栈
//             cout<<q->data;      //访问根结点
//             p = q->rchild;      //遍历右子树
//         }
//     }
// }

//19、后序遍历二叉树
void PostOrderTraverse(BiTree T)
{//后序遍历二叉树T的递归算法
    if(T)                               //若二叉树非空 
    {
        PostOrderTraverse(T->lchild);     //中序遍历左子树 
        PostOrderTraverse(T->rchild);     //中序遍历右子树
        cout<<T->data;                  //访问根结点 
    }
}

// //20
// LevelOrderTraverse(T)

//21、复制二叉树
void Copy(BiTree T, BiTree &NewT)
{//先序遍历复制一棵和T完全相同的二叉树
    if(T == NULL)
    {
        NewT = NULL;
        return;
    }
    else
    {
        NewT = new BiTNode;
        NewT->data = T->data;
        Copy(T->lchild, NewT->lchild);
        Copy(T->rchild, NewT->rchild);
    }
}

//22、二叉树深度
int Depth(BiTree T) 
{//后序遍历计算二叉树深度
    if(T == NULL)
        return 0;
    else
    {
        int m = Depth(T->lchild);
        int n = Depth(T->rchild);
        if(m > n)
            return (m + 1);
        else
            return (n + 1);
    }
}

//23、二叉树结点个数
int NodeCount(BiTree T)
{//统计二叉树T中的结点个数
    if(T == NULL)
        return 0;
    else
        return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;
}
//24、二叉树叶子结点个数
void LeavesCount(BiTree T)
{
    if(T)
    {
        if(!T->lchild && !T->rchild)
            cnt++;
        LeavesCount (T->lchild);
        LeavesCount (T->rchild);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_碗碗儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值