二叉树(C语言版)

二叉树

一、树的概念与结构

树是一种非线性的数据结构,它是由n(n>=0)个有限的结点,层往下依次延伸,由于它的逻辑形状,像一颗倒着的树,因此被称为树。

二、树的节点

(1)树有一个特殊的结点叫根节点,根节点无前驱结点。

(2)根节点的额每一个后继结点都可以成为一棵树,称为这棵树的子树,若根结点还有后继结点,那么它的后继结点也称为该数的子树。

(3)子树之间互为独立的树,不可以相交。

(4)除根节点之外,每个结点仅有一个父节点。

(5)一颗n个节点的树有n-1条边,因为根节点无前驱节点。

三、树的相关术语

(1)父结点/双亲结点:若一个结点含有子节点,这个节点称为其子节点的父节点,例:A是B的双亲节点。

(2)子结点/孩子结点:结点的后继结点,称为该结点的孩子结点,例:B、C是A的孩子结点。

(3)结点的度:一个节点孩子的个数就是他的度,例:A的度为2。

(4)叶子结点/终端结点:度为0的结点称为后继结点,例:D、E、F、G。

(5)分支结点/非终端结点:度不为0的结点,例:B、C、A。

(6)树的度:一棵树中最大结点度称为树的度,例:上图中树的度为2。

(7)兄弟节点:具有相同父节点的节点互称为兄弟结点,例:上图中的B、C。

(8)结点的层次:根所在的层为第一层,它的子结点为第二层,以此类推,例:上图中A为第一层,B、C为第二层,D、E、F、G为第三层。

(9)树的高度或深度:树中结点的最大层次,例:上图中树的最大层次为3。

(10)结点的祖先:从根结点所经分支上的所有节点,例:A是所有结点的祖先节点。

(11)路径:从树中的任意一结点出发,沿父节点到子节点,到达任意节点的路线,例:A到E的路径:A、B、E。

(12)子孙:以某结点为根的子树中任意一结点都称为该结点的子孙。

(13)森林:由m(m>0)棵互不相交的集合称为森林。

四、树的表示方法

树的表示方法有很多:双亲表示法、孩子表示法、孩子双亲表示法、以及孩子兄弟表示法。

这里我们采用最常用的孩子兄弟表示法来构建一颗二叉树。

1.孩子兄弟表示法代码结构:

struct TreeNode
{
    int data;//节点中的数据域
    struct TreeNode* child;//指向从左边开始第一个孩子结点。
    struct TreeNode* brother;//指向右边的下一个兄弟结点。
}

2.孩子兄弟表示法图形

五、二叉树的引入和概念

在树形结构当中我们最长用到的就是二叉树,那么二叉树又是什么呢?二叉树是由m个结点(m>=0)每个结点均有n(0<=n<=2),这样的树我们就称之为二叉树。

注:

(1)二叉树不存在度大于二的结点。

(2)二叉树有左右之分次序不能颠倒,因此二叉树树是有序树。

(3)m为0称为空树。

(4)二叉树由以下几种情况复合而成。

五、特殊的二叉树

1.满二叉树

(1)满二叉树

二叉树的每一层结点都达到最大值,这个树就是满二叉树。

(2)满二叉树的图形

2.完全二叉树

(1)完全二叉树

完全二叉树是由满二叉树所引出出来的,对于深度为k有n个节点的二叉树来说,当且仅当其每一个结点都与深度为k的满二叉树中编号1至n的结点一一对应时称之为完全二叉树,满二叉树是一种特殊的完全二叉树。

(2)完全二叉树的图形

六、二叉树的性质

(1)若规定根结点的层数为1,则一颗非空二叉树的第i层上至多有i的2i-1个结点。

(2)若规定根节点的层数为1,则深度为h的二叉树结点个数是2h-1。

(3)若规定根结点层数为1,具有n个结点则深度h = log(n+1)。

七、二叉树的存储结构

1.顺序结构

一般适用于存储完全二叉树,非完全二叉树的存储会有空间浪费。

2.链式结构存储

对于普通二叉树我们一般采用二叉链来存储,这样可以避免空间的浪费,我们下面的代码都是采用链式的存储结构。

八、二叉树功能的接口

typedef char DataType;
typedef struct TreeNode
{
    DataType data;
    struct TreeNode* left;
    struct TreeNode* right;
}BTNode;
​
BTNode* BuyNode(char x);
​
//前序遍历
void PreOrder(BTNode* root);
​
//中序遍历
void InOrder(BTNode* root);
​
//后序遍历
void PostOrder(BTNode* root);
​
//求结点个数
int BinaryTreeSize(BTNode* root);
​
//求叶子结点的个数
int BinaryTreeLastSize(BTNode* root);
​
//求第K层结点的个数
int BinaryTreeLeveSize(BTNode* root, int k);
​
//求二叉树高度
int BinaryTreeDepth(BTNode* root);
​
//找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, char x);
​
//二叉树的销毁
void BinaryTreeDestory(BTNode** root);
​
//层序遍历
void Leve1Order(BTNode* root);
​
//判断是否为完全二叉树
bool BinaryTreeComplete(BTNode* root);

九、二叉树功能的代码实现

1.先序遍历

//先序遍历
void PreOrder(BTNode* root)
{
    if (root == NULL)
    {
        return;
    }
    printf("%c ", root->data);
    PreOrder(root->left);
    PreOrder(root->right);
}

2.中序遍历

//中序遍历
void InOrder(BTNode* root)
{
    if (root == NULL)
    {
        return;
    }
    InOrder(root->left);
    printf("%c ", root->data);
    InOrder(root->right);
}

3.后序遍历

//后序遍历
void PostOrder(BTNode* root)
{
    if (root == NULL)
    {
        return;
    }
    PostOrder(root->left);
    PostOrder(root->right);
    printf("%c ",root->data);
}

4.求结点个数

//二叉树结点个数
int BinaryTreeSize(BTNode* root)
{
    if (root == NULL)
    {
        return 0;
    }
    return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

5.求叶子结点的个数

//叶子节点的个数
int BinaryTreeLastSize(BTNode* root)
{
    if (root == NULL)
    {
        return 0;
    }
    if (root->left == NULL && root->right == NULL)
    {
        return 1;
    }
    return BinaryTreeLastSize(root->left) + BinaryTreeLastSize(root->right);
}

6.求第k层结点个数

//求第K层结点的个数
int BinaryTreeLeveSize(BTNode* root, int k)
{
    if (root == NULL)
    {
        return 0;
    }
    if (k == 1)
    {
        return 1;
    }
    //注意--k和k-1
    return BinaryTreeLeveSize(root->left, k - 1) + BinaryTreeLeveSize(root->right, k - 1);
}

7.求二叉树的高度

//求二叉树高度
int BinaryTreeDepth(BTNode* root)
{
    if (root == NULL)
    {
        return 0;
    }
    int leftDepth = BinaryTreeDepth(root->left);
    int rightDepth = BinaryTreeDepth(root->right);
    return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}

8.找值为x的结点

//找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, char x)
{
    if (root == NULL)
    {
        return NULL;
    }
    if (root->data == x)
    {
        return root;
    }
    BTNode* ListNode = BinaryTreeFind(root->left, x);
    if (ListNode)
    {
        return ListNode;
    }
    BTNode* RightNode = BinaryTreeFind(root->right, x);
    if (RightNode)
    {
        return RightNode;
    }
    return NULL;
}

9.二叉树的销毁

//二叉树的销毁
void BinaryTreeDestory(BTNode** root)
{
    if (*root == NULL)
    {
        return;
    }
    BinaryTreeDestory(&((*root)->left));
    BinaryTreeDestory(&((*root)->right));
    free(*root);
    *root = NULL;
}

10.层序遍历

需要借助栈的结构来实现

//层序遍历
void Leve1Order(BTNode* root)
{
    Queue q;
    QueueInit(&q);
    QueuePush(&q, root);
    while (!QueueEmpty(&q))
    {
        BTNode* Top = QueueFront(&q);
        printf("%c ", Top->data);
        QueuePop(&q);
        if (Top->left != NULL)
        {
            QueuePush(&q, Top->left);
        }
        if (Top->right != NULL)
        {
            QueuePush(&q, Top->right);
        }
​
    }
    QueueDestory(&q);
}

11.判断二叉树是否为完全二叉树

需要借助栈的结构来实现

//判断是否为完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
    Queue q;
    QueueInit(&q);
    QueuePush(&q, root);
    while (!QueueEmpty(&q))
    {
        BTNode* Top = QueueFront(&q);
        QueuePop(&q);
        if (Top == NULL)
        {
            break;
        }
        QueuePush(&q, Top->left);
        QueuePush(&q, Top->right);
    }
    while (!QueueEmpty(&q))
    {
​
        if (QueueFront(&q) != NULL)
        {
            QueueDestory(&q);
            return false;
        }
        QueuePop(&q);
    }
    QueueDestory(&q);
    return true;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值