【数据结构】树之初体验

引言

在线性表中,元素之间的逻辑关系是平等(peer)的,没有等级之分,只有先后之分。但是在树中,元素之间是由复杂的族谱关系构成的。

树的定义

n个元素按照倒置的树的形态构成的一个集合。每一个元素对应树中的一个结点

(1)树根:一颗树中,有且仅有一个特定的称为根(Root)的结点;
(2)其余的结点可分为m(m≥0)个互不相交的子集Tl,T2,…,Tm,其中每个子集本身又是一棵树,并称其为根的子树(Subree)。

可见,树的定义是一个递归的定义。

与树相关的名词的解释

与树相关的概念很多,但是理解了 ,看起来就会觉得很有道理。记下还是好的,不然看其他文献,你不知道别人在说什么,而且考试最喜欢这个了- -。

空树            :一个结点也没有的树。

树的深度      :树的层次。下图中,树的深度为3

数的度         :树中所有结点度的最大值。下图中,A的度为2,B的度也为2,其他都是1,so,这个树的度为2.

有序树         :子树之间是有序的,是在意顺序的。

无序树         :子数之间相互交换位置不影响,不在意顺序。

叶子结点          :终端结点,没有子结点的结点。下图中,D,E,F都是叶子结点。

分支结点          :非终端结点。有子结点的结点。下图中,A,B,C都是分支结点。

结点的度          :一个结点拥有的子结点的个数(孩子的个数)。下图中,B有2个子结点,则它的度为2.

孩子结点          :一个结点的直接子结点,叫做这个结点的孩子结点。下图中,A的孩子为B,C。F是C的孩纸。

双亲(父结点)  :一个结点的父结点。除了root结点外,一个结点仅有一个双亲。下图中,A是B和C共同的父节点。

兄弟                :拥有同一个父结点的结点之间互为兄弟。下图中,B和C是兄弟,D和E是兄弟。

堂兄弟             :同一层的结点之间互为堂兄弟。下图中,D,E和F互为堂兄弟。

子孙                : 从一个结点派生出来的所有结点,都叫这个结点的子孙,包括它的孩子。下图中,B,C,E,D,F都是A的子孙。

森林: m个互不相关的树,构造森林。

二叉树

二叉树的度为2,也就是说,每一个结点的孩子最多有2个,并且,这2个孩纸是有左右之分的。即便是只有1个孩子,也分为左孩子,或右孩子。

二叉树的性质

1、二叉树的第i层上的节点数最多为 2i-1 个 (i>=1)

达到最多时,是按照满二叉树来考虑的。

2、 深度为k的二叉树至多有2k-1个结点(k≥1)。

根据性质1,可以得出:total_node = 20 + 21 + 22 + .....+ 2k-1

可以发现,这是一个公比为2的k项 等比数列,由等比公式求和得到total_node = 2K - 1

3、在任意一棵二叉树中,若终端(叶子)结点的个数为n0,度为2的结点数为n2,则有:n0=n2+1。

要证明这个性质,就要从点和线的方面去分析。

设:度为2的结点个数有n2个,度为1的结点有n1个,度为0  的叶子结点有n0个,树的总结点为total个。

树的总的 连线 的个数为L条。

①  total = n2 + n1 + n0

②  L = total - 1                      除了root结点,其他结点都是由头顶上的一条线引出来的。

③  L = 2*n2 + n1                   度为2的结点,必顶会向下引出2条线, 同理,度为1的结点会引出1条。

结合3个式子消元得:n0 = n2 + 1

  满二叉树

  除了叶子结点外,每一个结点的度都达到最大值2。

 完全二叉树

若一棵二叉树至多只有最下面的两层上结点的度数可以小于2,并且最下一层上的结点都集中在该层最左边的若干位置上,则此二叉树称为完全二叉树。

例如:在K层满二叉树的基础上,删去最下层,最右边的连续的n(n>=0)个叶子结点,即可得到一个K层完全二叉树。

特点:满二叉树一定是一个完全二叉树,反过来则不一定。

性质:

1、有n个结点的完全二叉树的深度为:int(log2n) + 1

int(log2n) 表示 不大于 log2n 的最大整数。

链式二叉树

和线性表一样,二叉树也有顺序实现和链式实现,为了简单起见,我们将精力集中在3种遍历算法上,所以选择了链式实现。顺序实现后面再提。

首先我们构建数据类型,假设存储的目标数据类型为char。

下面是一个5个元素的二叉树例子。结点的data分别为字符 A  ,B  ,C  ,E , F。每个结点除了含有data域,还有2个指针域,分别保存它的2个孩子的内存地址。

结点的地址是我假定的,目的上说明他们之间的关系。

typedef char DataType;       //目标储存对象类型

typedef struct node          //结点
{
    DataType data;
    struct node*left;
    struct node*right;

}Node;

typedef Node* LinkedBinaryTree;

通过手动硬编码的方式创建这个树,当然这个不是个好方法。然而我们在这里只想将精力放在理解3中遍历算法上,所以,这里就忍忍吧。相信理解了遍历,其他问题就会迎刃而解。

完整代码

#include<stdio.h>

typedef char DataType;

typedef struct node
{
    DataType data;
    struct node*left;
    struct node*right;

}Node;

typedef Node* LinkedBinaryTree; 

/***************function declare*******************/
void LinkedBinaryTree_init(LinkedBinaryTree *ptree);

int main()
{

    LinkedBinaryTree tree;

    LinkedBinaryTree_init(&tree);

    return 0;
}

void LinkedBinaryTree_init(LinkedBinaryTree *ptree)
{
    //root
    *ptree = new Node;
    (*ptree)->data = ‘A‘;

    //b
    Node*pb = new Node;
    pb->data = ‘B‘;

    //c
    Node*pc = new Node;
    pc->data = ‘C‘;

    //d
    Node*pd = new Node;
    pd->data = ‘D‘;

    //e
    Node*pe = new Node;
    pe->data = ‘E‘;

    //链接
    (*ptree)->left = pb; (*ptree)->right = pc;

    pb->left = pd;   pb->right = pe;  pc->left = NULL; pc->right = NULL;

    pd->left = NULL; pd->right = NULL; pe->left = NULL; pe->right = NULL;

}

至此,我们已近创建好了树。好了,先歇息歇息,下一站:二叉树的遍历

时间: 2024-11-09 00:38:19

【数据结构】树之初体验的相关文章

【Spark深入学习 -15】Spark Streaming前奏-Kafka初体验

----本节内容------- 1.Kafka基础概念 1.1 出世背景 1.2 基本原理 1.2.1.前置知识 1.2.2.架构和原理 1.2.3.基本概念 1.2.4.kafka特点 2.Kafka初体验 2.1 环境准备 2.2 Kafka小试牛刀 2.2.1单个broker初体验 2.2.2 多个broker初体验 2.3 Kafka分布式集群构建 2.3.1 Kafka分布式集群构建 2.3.2 Kafka主题创建 2.3.3 生产者生产数据 2.3.4消费者消费数据 2.3.5消息的

我是如何初体验uglifyjs压缩JS的

一.故事总有其背景 年末将至,很多闲适的时间,于是刷刷微博,接触各种纷杂的信息——美其名曰“学习”.运气不错,遇到了一个新名词,uglifyjs. 据说是用来压缩JS文件的,据说还能优化JS,据说是基于node的,还据说比Google Closure Compiler更带感,哦?激起了我的好奇心.百之谷之,哟,相关的介绍还不少.然后折腾了个把小时,基本上知道了是个怎么回事. 我觉得吧,还是有些用的,即使是不是从事node开发的人,抽个小空,share之,于是就有了本文.人总有浮躁的时候,我也不例

Linux初体验(五)

Linux初体验(五) 文件通配符 绝对路径与相对路径 发邮件 file tree 文件通配符 用途说明 文件通配符是一种简洁高效的语句,主要用来精确搜索或模糊搜索文件.其用一个或多个特殊的字符来实现对真正字符的替换,从而完成相关的任务. 在Linux中,主要有以下文件通配符: *  匹配零个或多个字符 ?  匹配任意单个字符 ~  当前用户家目录 ~username  用户家目录  [0-9]  匹配一个数字范围 [a-z]  大写与小写字母 [A-Z]  大写字母 [ ]  匹配列表中的任意

Kotlin初体验

让我们从一个小例子开始,来看看 Kotlin 代码长什么样子.这个例子定义了一个 Person 类来表示"人",创建一个"人"的集合,查找其中年纪最大的人,并打印结果.尽管这是非常小的一段代码,从中也可以看到 Kotlin 许多有趣的特性.  我们对其中的一些特性做了标记,以便你可以方便地在本书后续的内容中找到它们.  代码简要地进行了解释,但是如果有些内容你现在还无法理解,请不要担心,稍后我们会详细讨论.  如果你想尝试运行这个例子,最简单的方法是使用 http:

Linux初体验(六)

Linux初体验(六) inode cp mv rm ln 时间戳(touch.stat) 环境: CentOS 6.8 inode 用途说明 索引节点,存放文件的元数据 一个索引节点就是一个表项,包含了文件的元数据信息,包括: - 文件类型,权限,UID, GID- 链接数(指向文件名路径名称的个数) - 文件的大小与时间戳- 指向磁盘上文件的数据块指针  - 有关文件的其他数据 inode 本质上是一种数据结构,包含了文件系统中各个文件的元数据:inode表就是一份包含了对应文件系统中的所有

MySQL数据库初体验(含MySQL数据库5.7.17手工编译安装)

MySQL数据库初体验 Ram:随机性访问存储器,断电丢失数据 内存Rom:只读访问存储器,不会丢失数据 管理存储的数据,数据的增删改查,数据的迁移,保证数据的私密性 1.数据库的基本概念2.数据库的发展3.主流的数据库介绍4.编译安装mysql5.操作mysql 数据库的基本概念 数据: 1.描述事物的符号记录称为数据(Data)2.包括数字,文字.图形.图像.声音.档案记录等3.以"记录"形式按统一-的格式进行存储 表: 1.将不同的记录组织在一-起,就形成了"表&quo

erlang 初体验

最近测试了一下 erlang的坑... 如不出意外.... 大家第一眼看到这语法... 心里第一句一定是"我擦.这TM都是啥!!!!!" 没有变量!!! 没有结构体!!! 没有循环!!! 好吧,至少我是这样想的. 找了半天..连个if也不知道怎么写.. 这记录一些基本常识.. -module(module_name)  %%定义模块 括号内的要和文件名相同. -export([fun1/1 fun2/2]) %%这里是导出2个函数对外使用  函数名/参数名. 一个简单的函数定义如下 f

linux初体验

第一次听到linux这个'词语'是在一次偶然的朋友聊天中朋友提到的,之前压根没听到过'这个东西',所以我可以说是个linux的新新手,菜鸟都不算. 截至到目前,我已经开始linux系统运维学习有差不多10天时间了.在没接触linux之前,我对它的认识仅仅是:它是个计算机系统.决定学习linux系统运维之前,自我以为运维应该是对系统的一些日常维护之类的,不会很难的东西,我更希望运维是个不难的东西,我个人很笨,对难的东西可能接受的很慢,所以我愿意认为运维是很简单的,这样我就可以轻轻松松的掌握运维相关

Java8初体验(二)Stream语法详解

原文链接:http://ifeve.com/stream/ 1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel aggregate operations. 我们来解读一下上面的那句话: Stream是元素的集合,这点让Stream看起来用些类似Iterator: 可以支持顺序和并行的对原Stream进行汇聚的操作: 大家可以把Stream当成一个高级版本的