Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >数据结构树的专题

数据结构树的专题

作者头像
用户2417870
发布于 2019-12-02 07:49:08
发布于 2019-12-02 07:49:08
40500
代码可运行
举报
文章被收录于专栏:g歌德ag歌德a
运行总次数:0
代码可运行

一、二叉树的基本操作

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>  
#include<stdlib.h>  
  
typedef char ElemType;  
  
typedef struct Node  
{  
    ElemType data;  
    struct Node *lchild, *rchild;  
} BiTree;  
  
BiTree *createBT()  //键盘输入创建二叉树  
{  
    BiTree *b;  
    ElemType ch;  
    scanf("%c", &ch);  
    fflush(stdin);  // 清空键盘缓冲  
    if(ch != '#')   // #表示空  
    {  
        b = (BiTree *)malloc(sizeof(BiTree));  
        b->data = ch;  
        printf("请输入%c的左孩子:", ch);  
        b->lchild = createBT();  
        printf("请输入%c的右孩子:", ch);  
        b->rchild = createBT();  
    }  
    else  
        b = NULL;  
    return b;  
}  
  
void createBT(BiTree *&b, char *s)  //用括号表示法的字符串s生成二叉树b  
{  
    BiTree *st[100], *t;    //st存放树结点的栈  
    int top = -1;  
    int k;      //k=1表示左孩子, k=2表示右孩子  
      
    b = NULL;  
    while(*s)  
    {  
        switch(*s)  
        {  
        case '(':  
            top++;  
            st[top] = t;  
            k = 1;      //准备处理左孩子  
            break;  
        case ')':  
            top--;  
            break;  
        case ',':  
            k = 2;      //准备处理右孩子  
            break;  
        default:  
            t = (BiTree *)malloc(sizeof(BiTree));  
            t->data = *s;  
            t->lchild = t->rchild = NULL;  
            if(b == NULL)  
                b = t;  
            else  
            {  
                switch(k)  
                {  
                case 1:  
                    st[top]->lchild = t; break;  
                case 2:  
                    st[top]->rchild = t; break;  
                }  
            }  
        }  
        s++;  
    }  
}  
  
BiTree *createBT_PreIn(char *pre, char *in, int n)  //由先序序列pre和中序序列in的n个字符构造二叉树并返回  
{  
    BiTree *b;  
    int i;  
    if(n<=0)  
        return NULL;  
    b = (BiTree *)malloc(sizeof(BiTree));  
    b->data = *pre;  
    for(i=0; i<n; i++)  
        if(in[i] == *pre)  
            break;  
    b->lchild = createBT_PreIn(pre+1, in, i);  
    b->rchild = createBT_PreIn(pre+i+1, in+i+1, n-i-1);  
  
    return b;  
}  
  
BiTree *createBT_InPost(char *in, char *post, int n)    //由中序序列in和后序序列post的n个字符构造二叉树并返回  
{  
    BiTree *b;  
    int i;  
    if(n <= 0)  
        return NULL;  
    b = (BiTree *)malloc(sizeof(BiTree));  
    b->data = *(post + n - 1);  
    for(i=0; i<n; i++)  
        if(in[i] == b->data)  
            break;  
    b->lchild = createBT_InPost(in, post, i);  
    b->rchild = createBT_InPost(in+i+1, post+i, n-i-1);  
  
    return b;  
}  
  
void preOrder(BiTree *b)    //先序遍历二叉树  
{  
    if(b)  
    {  
        printf("%c", b->data);  
        preOrder(b->lchild);  
        preOrder(b->rchild);  
    }  
}  
  
void inOrder(BiTree *b)     //中序遍历二叉树  
{  
    if(b)  
    {  
        inOrder(b->lchild);  
        printf("%c", b->data);  
        inOrder(b->rchild);  
    }  
}  
  
void postOrder(BiTree *b)   //后序遍历二叉树  
{  
    if(b)  
    {  
        postOrder(b->lchild);  
        postOrder(b->rchild);  
        printf("%c", b->data);  
    }  
}  
  
void dispBT(BiTree *b)      //括号法输出二叉树  
{  
    if(b)  
    {  
        printf("%c", b->data);  
        if(b->lchild || b->rchild)  
        {  
            printf("(");  
            dispBT(b->lchild);  
            if(b->rchild)  
                printf(",");  
            dispBT(b->rchild);  
            printf(")");  
        }  
    }  
}  
  
int BT_depth(BiTree *b)     //返二叉树的高度  
{  
    int dep1, dep2;  
    if(b == NULL)  
        return 0;  
  
    dep1 = BT_depth(b->lchild);  
    dep2 = BT_depth(b->rchild);  
      
    return (dep1 > dep2 ? dep1 :dep2) + 1;  
}  
  
int leafNum(BiTree *b)      //统计叶子节点的个数  
{  
    if(b == NULL)   
        return 0;  
    if(b->lchild == NULL && b->rchild == NULL)  
        return 1;  
    return leafNum(b->lchild) + leafNum(b->rchild);  
}  
  
BiTree *findNode(BiTree *b, ElemType x)     //查找二叉树b中值为x的结点,并返回该结点的指针  
{  
    BiTree *p;  
    if(b == NULL)  
        return NULL;  
    else if(b->data == x)  
        return b;  
    else  
    {  
        p = findNode(b->lchild, x);  
        if(p != NULL)  
            return p;  
        else  
            return findNode(b->rchild, x);  
    }  
}  
  
void destroyBT(BiTree *&b)  //销毁二叉树  
{  
    if(b)  
    {  
        destroyBT(b->lchild);  
        destroyBT(b->rchild);  
        free(b);  
        b = NULL;  
    }  
}  
  
void main()  
{  
    BiTree *b;  
    char *s = "A(B(,X),C)";  
    char *pre = "ABXC";  
    char *in = "BXAC";  
    char *post = "XBCA";  
  
    //键盘输入二叉树  
    //printf("输入根结点(#表示空):");  
    //b = createBT();  
  
    //括号表示法输入二叉树  
    //createBT(b, s);  
  
    //先序序列和中序序列输入二叉树  
    //b = createBT_PreIn(pre, in, 4);  
  
    //中序序列和后序序列输入二叉树  
    b = createBT_InPost(in, post, 4);  
  
    printf("\n先序序列:"); preOrder(b);   
    printf("\n中序序列:"); inOrder(b);  
    printf("\n后序序列:"); postOrder(b);  
    printf("\n括号表示法:"); dispBT(b);  
    printf("\n深度:%d" , BT_depth(b));   
    printf("\n叶子数:%d\n", leafNum(b));  
    destroyBT(b);  
}  

二、树、森林与二叉树的转换

1、树转换为二叉树

由于二叉树是有序的,为了避免混淆,对于无序树,我们约定树中的每个结点的孩子结点按从左到右的顺序进行编号。

将树转换成二叉树的步骤是: (1)加线。就是在所有兄弟结点之间加一条连线; (2)抹线。就是对树中的每个结点,只保留他与第一个孩子结点之间的连线,删除它与其它孩子结点之间的连线; (3)旋转。就是以树的根结点为轴心,将整棵树顺时针旋转一定角度,使之结构层次分明。

2、森林转换为二叉树

森林是由若干棵树组成,可以将森林中的每棵树的根结点看作是兄弟,由于每棵树都可以转换为二叉树,所以森林也可以转换为二叉树。

将森林转换为二叉树的步骤是: (1)先把每棵树转换为二叉树; (2)第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子结点,用线连接起来。当所有的二叉树连接起来后得到的二叉树就是由森林转换得到的二叉树。

3、二叉树转换为树

二叉树转换为树是树转换为二叉树的逆过程,其步骤是: (1)若某结点的左孩子结点存在,将左孩子结点的右孩子结点、右孩子结点的右孩子结点……都作为该结点的孩子结点,将该结点与这些右孩子结点用线连接起来; (2)删除原二叉树中所有结点与其右孩子结点的连线; (3)整理(1)和(2)两步得到的树,使之结构层次分明。

4、二叉树转换为森林

二叉树转换为森林比较简单,其步骤如下: (1)先把每个结点与右孩子结点的连线删除,得到分离的二叉树; (2)把分离后的每棵二叉树转换为树; (3)整理第(2)步得到的树,使之规范,这样得到森林。

根据树与二叉树的转换关系以及二叉树的遍历定义可以推知,树的先序遍历与其转换的相应的二叉树的先序遍历的结果序列相同;树的后序遍历与其转换的二叉树的中序遍历的结果序列相同;树的层序遍历与其转换的二叉树的后序遍历的结果序列相同。由森林与二叉树的转换关系以及森林与二叉树的遍历定义可知,森林的先序遍历和中序遍历与所转换得到的二叉树的先序遍历和中序遍历的结果序列相同。

三、AVL平衡二叉树

四、哈夫曼树的应用

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
实验三 二叉树的基本操作(建立)及遍历
实验三 二叉树的基本操作(建立)及遍历 实验目的 1.学会实现二叉树结点结构和对二叉树的基本操作。 2.通过对二叉树遍历操作的实现,理解二叉树各种操作,学会利用递归方法编写对二叉树等类似递归数据结构进行处理的算法。 实验要求 1.认真阅读和掌握和本实验相关的教材内容。 2.编写完整程序完成下面的实验内容并上机运行。 实验内容 1.编写程序输入二叉树的结点个数和结点值,构造下图所示的二叉树。 2.编写程序,采用中序遍历的递归和非递归算法对此二叉树进行遍历。
谙忆
2021/01/20
7500
实验三 二叉树的基本操作(建立)及遍历
那些未说出口的告白,终会顺着线索遍历到你的心底——数据结构算法之树算法习题试炼
求某层的结点个数、每层的结点个数、树的最大宽度等,都可采用与此题类似的思想。当然,此题可编写为递归算法,其实现如下:
盛透侧视攻城狮
2025/03/10
720
那些未说出口的告白,终会顺着线索遍历到你的心底——数据结构算法之树算法习题试炼
数据结构学习—树(1)
树结构中,位于同一层的节点之间互为兄弟节点。例如,图 1 的普通树中,节点 A、B 和 C 互为兄弟节点,而节点 D、E 和 F 也互为兄弟节点。孩子兄弟表示法,采用的是链式存储结构,其存储树的实现思想是:从树的根节点开始,依次用链表存储各个节点的孩子节点和兄弟节点。 因此,该链表中的节点应包含以下 3 部分内容
用户5513909
2023/04/25
4320
数据结构学习—树(1)
树的基本操作
而我们在数据结构中所探讨的与此有相似之处,又与此有莫大的不同。我们数据结构吗,要从树这种结构说起。
兰舟千帆
2022/07/17
2680
树的基本操作
数据结构——树和二叉树
满二叉树是叶子一个也不少的树,而完全二叉树虽然前n-1层是满的,但最底层却允许在右边缺少连续若干个结点。满二叉树是完全二叉树的一个特例。
ruochen
2021/06/29
7310
我的思念像满二叉树般疯长,每个空指针都指向你的方向——全程动画可视化数据结构算法之二叉树
盛透侧视攻城狮
2025/03/02
1170
我的思念像满二叉树般疯长,每个空指针都指向你的方向——全程动画可视化数据结构算法之二叉树
【数据结构】树代码实现
一对多:我们要存放的是所有节点存放的孩子,存放所有节点的东西是数组,由于存放的孩子的数量不固定,所以选用链表。
CtrlX
2023/03/21
6730
【数据结构】树代码实现
数据结构-二叉树遍历总结
chaibubble
2018/01/02
6330
数据结构-二叉树遍历总结
PHP数据结构-二叉树的遍历及逻辑操作
上篇文章我们讲了许多理论方面的知识,虽说很枯燥,但那些都是我们今天学习的前提,一会看代码的时候你就会发现这些理论知识是多么地重要了。首先,我们还是要说明一下,我们学习的主要内容是二叉树,因为二叉树是最典型的一种树的应用,不管是考试还是面试,它都是必知必学的内容。
硬核项目经理
2021/05/11
4170
PHP数据结构-二叉树的遍历及逻辑操作
数据结构学习笔记(树、二叉树)
树(一对多的数据结构) 树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。在任意一颗非空树种: (1)有且仅有一个特定的称为根(Root)的结点; (2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1、T2、......、Tn,其中每一个集合本身又是一棵树,并且称为根的子树。 对于树的定义还需要强调两点: 1.n>0时根结点是唯一的,不可能存在多个根结点,数据结构中的树只能有一个根结点。 2.m>0时,子树的个数没有限制,但它们一定是互不相交的。 结点分类: 结点拥有的子
希希里之海
2018/05/16
6790
数据结构实验之二叉树实验基础
1、二叉树:二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分 [1] 。
LucianaiB
2025/05/28
730
数据结构实验之二叉树实验基础
数据结构—树与二叉树
之前谈到的线性表、栈和队列都是一对一的数据结构,但是现实中也存在很多一对多的数据结构,这篇要写的就是一种一对多的数据结构———树。全文分为如下几部分:
张俊红
2018/08/23
6430
【数据结构】C语言实现树和森林的遍历
在上一篇内容中我们介绍了树、森林与二叉树之间的相互转换,其核心逻辑就是通过孩子兄弟存储结构对树、森林进行存储,完成存储后的树和森林就被转换成了一棵二叉树。
蒙奇D索隆
2025/03/19
920
【数据结构】C语言实现树和森林的遍历
二叉树的性质和常用操作代码集合
二叉树的性质和常用操作代码集合 性质: 二叉树的性质和常用代码操作集合 性质1:在二叉树的第i层上至多有2^i-1个结点 性质2:深度为k的二叉树至多有2^k - 1个结点 性质3:对任意一棵二叉树T,若终端结点数为n0,而其度数为2的结点数为n2,则n0 = n2 + 1 满二叉树:深度为k且有2^-1个结点的树 完全二叉树:深度为k,结点数为n的二叉树,如果其结点1~n的位置序号分别与等高的满二叉树的结 点1~n的位置序号一一对应,则为完全二叉树
Steve Wang
2018/02/05
7240
【编程练习】复习一下树的遍历
深度有限遍历记录层数:增加一个level //深度优先遍历 void depthFirstSearch(Tree root){ stack<pair<int, Node *> > nodeStack; //使用C++的STL标准模板库 nodeStack.push(make_pair(0, root)); Node *node; while(!nodeStack.empty()){ node = nodeStack.top().second;
流川疯
2022/05/06
1720
数据结构 第五章 树和二叉树
树:n(n≥0)个结点的有限集合。 当n=0时,称为空树; 任意一棵非空树满足以下条件: ⑴ 有且仅有一个特定的称为根的结点; ⑵ 当n>1时,除根结点之外的其余结点被分成m(m>0)个互不相交的有限集合T1,T2,… ,Tm,其中每个集合又是一棵树,并称为这个根结点的子树。 结点的度:结点所拥有的子树的个数。 树的度:树中各结点度的最大值。 叶子结点:度为0的结点,也称为终端结点。 分支结点:度不为0的结点,也称为非终端结点。 孩子、双亲:树中某结点子树的根结点称为这个结点的孩子结点,这个结点称为它孩子结点的双亲结点; 兄弟:具有同一个双亲的孩子结点互称为兄弟。 路径:如果树的结点序列n1, n2, …, nk有如下关系:结点ni是ni+1的双亲(1<=i<k),则把n1, n2, …, nk称为一条由n1至nk的路径;路径上经过的边的个数称为路径长度。 祖先、子孙:在树中,如果有一条路径从结点x到结点y,那么x就称为y的祖先,而y称为x的子孙。 结点所在层数:根结点的层数为1;对其余任何结点,若某结点在第k层,则其孩子结点在第k+1层。 树的深度:树中所有结点的最大层数,也称高度。 层序编号:将树中结点按照从上层到下层、同层从左到右的次序依次给他们编以从1开始的连续自然数。 有序树、无序树:如果一棵树中结点的各子树从左到右是有次序的,称这棵树为有序树;反之,称为无序树。 森林:m (m≥0)棵互不相交的树的集合。 同构:对两棵树,若通过对结点适当地重命名,就可以使这两棵树完全相等(结点对应相等,结点对应关系也相等),则称这两棵树同构。 前序遍历:树的前序遍历操作定义为: 若树为空,不进行遍历;否则 ⑴ 访问根结点; ⑵ 按照从左到右的顺序前序遍历根结点的每一棵子树。 后序遍历:树的后序遍历操作定义为: 若树为空,则遍历结束;否则 ⑴ 按照从左到右的顺序后序遍历根结点的每一棵子树; ⑵ 访问根结点。 层序遍历:树的层序遍历操作定义为: 从树的第一层(即根结点)开始,自上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。
Twcat_tree
2022/11/29
3010
数据结构C#版笔记--树与二叉树
                图1 上图描述的数据结构就是“树”,其中最上面那个圈圈A称之为根节点(root),其它圈圈称为节点(node),当然root可以认为是node的特例。 树跟之前学习过的线性结构不同,它是一对多的非线性结构,具有二个基本特点: 1、根节点(root)没有前驱节点,除root之外的所有节点有且只有一个前驱节点 2、树中的所有节点都可以有0个或多个后继节点。 所以下面这些歪瓜咧枣,不能算是树:                 图2 下是是一些烦人但是很重要的术语:   1、
菩提树下的杨过
2018/01/23
1.5K0
数据结构C#版笔记--树与二叉树
【数据结构】建立二叉树以及哈夫曼树及哈夫曼编码
文章目录 5.4.1 方式 5.4.2 由先根和中根遍历序列建二叉树 5.4.3 由后根和中根遍历序列建二叉树 5.4.4 由标明空子树的先根遍历建立二叉树 5.4.5 由完全二叉树的顺序存储结构建立二叉链式存储结构 5.5 哈夫曼树及哈夫曼编码 5.5.1 基本概念 5.5.2 最优二叉树 5.5.3 构建哈夫曼树 5.5.4 哈夫曼编码 5.5.5 哈夫曼编码类 5.4.1 方式 四种方式可以建立二叉树 由先根和中根遍历序列建二叉树 由后根和中根遍历序列建二叉树 由标明空子树的先根遍
陶然同学
2023/02/26
1.1K0
【数据结构】建立二叉树以及哈夫曼树及哈夫曼编码
数据结构实验报告,二叉树的基本操作(C语言)
通过完全前序序列创建一棵二叉树,完成如下功能: 1)创建二叉树; 2)输出二叉树的前序遍历序列; 3)输出二叉树的中序遍历序列; 4)输出二叉树的后序遍历序列; 5)统计二叉树的结点总数; 6)统计二叉树中叶子结点的个数;
命运之光
2024/03/20
3940
数据结构实验报告,二叉树的基本操作(C语言)
二叉树的基本操作(C 语言版)包含递归和非递归算法
二叉树是每个结点最多有两个子树的树结构,常被用于实现二叉查找树和二叉堆。二叉树是链式存储结构,用的是二叉链,本质上是链表。二叉树通常以结构体的形式定义,如下,结构体内容包括三部分:本节点所存储的值、左孩子节点的指针、右孩子节点的指针。
零式的天空
2022/03/28
4K0
推荐阅读
相关推荐
实验三 二叉树的基本操作(建立)及遍历
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验