二叉树的基本操作

树的定义

 树的特点

树的模型 

 

#二叉树 

 二叉树是另一种树形结构,其特点是每个节点最多有两个子树,并且二叉树的子树有左右之分,其次序不能任意颠倒。与树相似,二叉树也是以递归的形式定义(即每次定义时候的操作是重复的即为根节点,左子树,右子树,然后左子树为根节点再次重复操作),当集合中的节点数为0时,为空二叉树,或者由一个根节点和两个互不相交的被称为根的左子树和右子树组成,左子树和右子树分别是一棵二叉树        

二叉树的特例

满二叉树和完全二叉树 

满二叉树即为每个父节点的左右子树都不为空,而完全二叉树的定义为右边可以为空但是左边不能为空,例如去除完全二叉树的第十一个节点,这个时候就不叫作二叉树,但是如果保留第十一个节点,去除第十二个节点这个时候还是完全二叉树。

树的抽象数据结构定义

//创建树的结点
typedef struct BiTnode{
    Elemtype c;
    struct BiTnode *Lchild; //左子树
    struct BiTnode *Rchild; //右子树
}BiTnode, *BiTree;

#二叉树层次建树的实现

在上面树的模型那个图片中提到了树的层数,而二叉树的层次创建就是一层一层创建二叉树,如当你存储元素为字符类型时,创建二叉树存储abcdefg的过程就为 

 1.先将根节点放入树中,将根节点入队,当创建第二个节点时候,判断左右子树是否为空,如果左子树为空,将结点放入根节点的左子树,如果左子树满,右子树空,那么就将结点放入右子树中,在放入根节点的左右子树的同时也要将结点入队,当根节点满的时候,队列中访问根节点的指针就可以移动到下一个结点,这个结点就成为了新的根节点,在队列中存储的结点都可以作为根节点存储左右子树,这样就创建好了一颗二叉树,这也就是二叉树的层次创建,主要就是利用了队列尾插的特性以及二叉树是由一颗颗小的子树组成的特性。

 代码实现:

#include<stdio.h>
#include <cstdlib>


//完成二叉树层次建树的实现
typedef char Elemtype;
//创建树的结点
typedef struct BiTnode{
    Elemtype c;
    struct BiTnode *Lchild; //左子树
    struct BiTnode *Rchild; //右子树
}BiTnode, *BiTree;

//辅助队列的作用,帮助判断父节点元素左右子树是否为空
//定义辅助队列结构体  用链表实现
typedef struct tag{
    BiTree p; //父节点元素的地址
    struct tag *next;
}tag_t,*ptag_t;


int main() {
    //第一步创建树
    BiTree tree = NULL;
    //创建结点指针
    BiTnode *bp = NULL;
    //创建辅助队列指针
    ptag_t head = NULL,tail = NULL, pcur = NULL,listpnew = NULL; //定义辅助队列的头指针与尾指针,先进先出
    char c;
    while (scanf("%c",&c))
    {
        if(c == '\n')
        {
            break;
        } else{
            listpnew = (tag_t *) calloc(1,sizeof (tag_t));
            bp = (BiTnode*) calloc(1,sizeof (BiTnode)); //calloc函数在申请的时候会自动初始化结构体内容为0
            bp->c = c;
            //判断树是否为空 如果树为空将第一个结点作为根节点
            if(tree == NULL)
            {
                tree = bp;
                head = listpnew;//队列中第一个结点作为头节点
                tail = head;
                head->p = bp;//将根节点放入头节点
                pcur = head;
            } else{
                listpnew->p = bp;
                tail->next = listpnew;
                tail = listpnew;
                tail->next = NULL;
                //若左子树为空
                if(pcur->p->Lchild == NULL)
                {
                    pcur->p->Lchild = tail->p;
                } else if(pcur->p->Rchild == NULL)
                {
                    pcur->p->Rchild = tail->p;
                    pcur = pcur->next; //此时二叉树父节点放满 pcur进入下个父节点
                }
            }
        }

    }

    return 0;
}

 下面只介绍二叉树的三种常见的遍历方式,先序遍历,中序遍历,后序遍历。他遍历的方式于创建树递归的方式相同,都是根,左,右,

 

 这里只介绍先序遍历二叉树,另外两种二叉树与此种方法思想相同,二叉树的遍历其实是分成每个子树的遍历,子树的遍历顺序为根,左,右, 由于先序遍历的过程为访问根节点,先序遍历左子树,先序遍历右子树,所以每次按照这种顺序的时候,左右子树就可以作为结点进行先序遍历,那么再每次访问完根节点之后,这种方法一定会先去遍历所有的左子树,当查找左子树结点为NULL时递归返回,再去依次遍历右子树。

 具体代码实现如下


//先序遍历  每棵子树的遍历顺序都是根左右
void PreQuery(BiTree tree)
{
    if(tree != NULL)
    {
        printf("%c",tree->c);
        PreQuery(tree->Lchild);
        PreQuery(tree->Rchild);
    }
}
//中序遍历  每棵子树的遍历顺序都是左根右
void MidQuery(BiTree tree)
{
    if(tree != NULL)
    {
        PreQuery(tree->Lchild);
        printf("%c",tree->c);
        PreQuery(tree->Rchild);
    }
}
//后序遍历  每棵子树的遍历顺序都是左右根
void EndQuery(BiTree tree)
{
    if(tree != NULL)
    {
        PreQuery(tree->Lchild);
        PreQuery(tree->Rchild);
        printf("%c",tree->c);
    }
}

 #二叉树的层次遍历

 二叉树的层次遍历就是从第一层开始,从左到右将所有结点值给打印出来,实现过程如下,每个结点出队的时候会将结点值打印,因此根据辅助先进先出的特性,就可以实现对二叉树的层次遍历

//二叉树的层次遍历
void LevelOrder(BiTree tree)
{
    LinkQueque Queque; //辅助队列
    BiTree outp; //保存出队结点,出队相当于打印
    InitQueque2(Queque);
    EnQueque2(Queque,tree); //根结点入队
    while (!IsEmpty(Queque))
    {
        DeQueque(Queque,outp); //出队
        putchar(outp->c);      //打印出队值
        if(outp->Lchild!=NULL)  // 如果根节点左结点错在,那么左节点入队
        {
            EnQueque2(Queque,outp->Lchild);
        } else if(outp->Rchild != NULL) // 如果右节点左结点错在,那么左节点入队
        {
            EnQueque2(Queque,outp->Rchild);
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉树是一种非常重要的数据结构,它的基本操作包括创建、销毁、遍历、查找等。下面是二叉树基本操作的实现方法: 1. 创建二叉树:通过前序遍历的数组构建二叉树,其中 '#' 表示空节点。具体实现方法可以参考引用中的 BinaryTreeCreate 函数。 2. 销毁二叉树:遍历二叉树,依次释放每个节点的内存空间。具体实现方法可以参考引用中的 BinaryTreeDestory 函数。 3. 遍历二叉树二叉树的遍历包括前序遍历、中序遍历、后序遍历和层序遍历。具体实现方法可以参考引用中的 BinaryTreePrevOrder、BinaryTreeInOrder、BinaryTreePostOrder 和 BinaryTreeLevelOrder 函数。 4. 查找二叉树节点:在二叉树中查找值为 x 的节点,具体实现方法可以参考引用中的 BinaryTreeFind 函数。 5. 计算二叉树节点个数:计算二叉树中节点的个数,具体实现方法可以参考引用[2]中的 BinaryTreeSize 函数。 6. 计算二叉树叶子节点个数:计算二叉树中叶子节点的个数,具体实现方法可以参考引用中的 BinaryTreeLeafSize 函数。 7. 计算二叉树第 k 层节点个数:计算二叉树中第 k 层节点的个数,具体实现方法可以参考引用中的 BinaryTreeLevelKSize 函数。 8. 判断二叉树是否是完全二叉树:判断二叉树是否是完全二叉树,具体实现方法可以参考引用中的 BinaryTreeComplete 函数。 9. 计算二叉树的深度:计算二叉树的深度,具体实现方法可以参考引用中的 BinaryTreeDeep 函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值