前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据结构-二叉树遍历总结

数据结构-二叉树遍历总结

作者头像
chaibubble
发布2018-01-02 11:03:16
5470
发布2018-01-02 11:03:16
举报

二叉树结构

二叉树是一种特殊的树,每个父结点最多只能用有两个子结点。

这里写图片描述
这里写图片描述

在树中,按照结点的“继承”关系可以分为父结点和子结点; 按照结点的位置关系可以分为根结点,中间结点和叶结点。 其中叶结点没有子结点。 我们用结点中的数字代表结点,那么在上图中:10为根结点;6、14为中间结点;4、8、12、16为叶节点。

二叉树存储结构

二叉树结构可以使用链式和顺序两种方式实现,其中比较常用的链式存储结构:

链式结构

代码语言:javascript
复制
typedef char TElemType; 
typedef struct BiTNode  /* 结点结构 */
{
   TElemType data;      /* 结点数据 */
   struct BiTNode *lchild,*rchild; /* 左右孩子指针 */
}BiTNode,*BiTree;

也可以写成这样,更清晰一些:

代码语言:javascript
复制
typedef char TElemType;   
typedef struct BiTNode{  
    TElemType data;  
    struct BiTNode* lchild;  
    struct BiTNode* rchild;  
}BiTNode;    
typedef BiTNode* BiTree;          

顺序结构

代码语言:javascript
复制
#define LENGTH 100  
typedef char datatype;  
typedef struct node{  
    datatype data;  
    int lchild,rchild;  
    int parent;  
}Node;  

Node tree[LENGTH];  
int length;  
int root;  

本质上是一个结构体数组。

二叉树遍历

在二叉树中最重要的操作大概就是遍历,如链表这样的数据结构,遍历的方式是唯一的,因为我们只知道链表的头结点,遍历到一个结点时也只知道下一个结点(单链表),但是在树中却有多种遍历方式,通常有: 前序遍历:根结点—>左子结点—>右子结点,10、6、4、8、14、12、16; 中序遍历:左子结点—>根结点—>右子结点,4、6、8、10、12、14、16; 后序遍历:左子结点—>右子结点—>根结点,4、8、6、12、16、14、10; 层序遍历:第一层—>第二层—>第n层,10、6、14、4、8、12、16;

代码实现

遍历操作可以使用循环和递归的方式实现,其中递归可以使代码变的很简洁易懂,同样树的结构越复杂,递归的层数就会越深,但是总体上递归的方法更常用。

前序遍历:

代码语言:javascript
复制
void PreOrderTraverse(BiTree T)
{ 
    if(T==NULL)
        return;
    printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
    PreOrderTraverse(T->lchild); /* 再先序遍历左子树 */
    PreOrderTraverse(T->rchild); /* 最后先序遍历右子树 */
}

中序遍历:

代码语言:javascript
复制
void InOrderTraverse(BiTree T)
{ 
    if(T==NULL)
        return;
    InOrderTraverse(T->lchild); /* 中序遍历左子树 */
    printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
    InOrderTraverse(T->rchild); /* 最后中序遍历右子树 */
}

后序遍历:

代码语言:javascript
复制
void PostOrderTraverse(BiTree T)
{
    if(T==NULL)
        return;
    PostOrderTraverse(T->lchild); /* 先后序遍历左子树  */
    PostOrderTraverse(T->rchild); /* 再后序遍历右子树  */
    printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
}

以上三种遍历方式很相似,只是递归的输入不同,而这就决定着遍历的顺序,我们拿前序遍历举个例子:

这里写图片描述
这里写图片描述

还是上面这个图,此时函数的输入为树的根结点,这是一个BiTree 类型的变量,前面定义了它是一个指针,打印10,此时没有进入递归,深度为0:

这里写图片描述
这里写图片描述

执行PreOrderTraverse(T->lchild)递归两次后打印6、4,此时打印6的那次递归深度是1,打印4的递归深度是2:

这里写图片描述
这里写图片描述

此时执行PreOrderTraverse(T->lchild),但是4没有左子结点,进入一下第3层递归又退出回到第2层,执行PreOrderTraverse(T->rchild)但是4没有右子结点,进入一下第3层递归又退出回到第2层,此时结点4已经执行完了,返回第1层(结点6),执行PreOrderTraverse(T->rchild),打印8:

这里写图片描述
这里写图片描述

递归又到了第2层,显然又要退回到第1层,但是到了第1层发现第1层也执行完了,退回到第0层(结点10),执行PreOrderTraverse(T->rchild),打印14,于是后面就一样了,直到打印了16之后,从第2层开始退出,退到第0层之后发现第0层也执行完了:

这里写图片描述
这里写图片描述

最后,树的层序遍历与上面三种遍历方式不同,而且也不仅仅能用在二叉树,这个在本博客中先不涉及,后面补上。

其他操作

二叉树除了遍历外,还有一些其他的基本操作:

构建空二叉树:

代码语言:javascript
复制
typedef int Status; 
Status InitBiTree(BiTree *T)
{ 
    *T=NULL;
    return OK;
}

销毁二叉树:

代码语言:javascript
复制
void DestroyBiTree(BiTree *T)
{ 
    if(*T) 
    {
        if((*T)->lchild) /* 有左孩子 */
            DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */
        if((*T)->rchild) /* 有右孩子 */
            DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */
        free(*T); /* 释放根结点 */
        *T=NULL; /* 空指针赋0 */
    }
}

创建二叉树:

代码语言:javascript
复制
void CreateBiTree(BiTree *T)
{ 
    TElemType ch;

    ch=str[index++];

    if(ch=='#') 
        *T=NULL;
    else
    {
        *T=(BiTree)malloc(sizeof(BiTNode));
        if(!*T)
            exit(OVERFLOW);
        (*T)->data=ch; /* 生成根结点 */
        CreateBiTree(&(*T)->lchild); /* 构造左子树 */
        CreateBiTree(&(*T)->rchild); /* 构造右子树 */
    }
}

判断二叉树是否存在:

代码语言:javascript
复制
Status BiTreeEmpty(BiTree T)
{ 
    if(T)
        return FALSE;
    else
        return TRUE;
}

返回二叉树深度:

代码语言:javascript
复制
int BiTreeDepth(BiTree T)
{
    int i,j;
    if(!T)
        return 0;
    if(T->lchild)
        i=BiTreeDepth(T->lchild);
    else
        i=0;
    if(T->rchild)
        j=BiTreeDepth(T->rchild);
    else
        j=0;
    return i>j?i+1:j+1;
}  
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-08-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二叉树结构
  • 二叉树存储结构
  • 二叉树遍历
  • 代码实现
  • 其他操作
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档