树之二叉树

树的概念

树(Tree)是 n ( n ≥ 0 ) n(n≥0) nn0个节点的有限集合T,它满足两个条件 :

  1. 有且仅有一个特定的称为根(Root)的节点;
  2. 其余的节点可以分为 m ( m ≥ 0 ) m(m≥0) mm0个互不相交的有限集合 T 1 、 T 2 、 … … 、 T m T1、T2、……、Tm T1T2……Tm,其中每一个集合又是一棵树,并称为其根的子树

表示方法 :树形表示法目录表示法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AvHBp2va-1666516025397)(https://raw.githubusercontent.com/zfr010503/huaqing/master/img/202210231627834.png)]

  • 一个节点的子树的个数称为该节点的度数
  • 一棵树的度数是指该树中节点的最大度数。
  • 度数为零的节点称为树叶终端节点
  • 度数不为零的节点称为分支节点
  • 除根节点外的分支节点称为内部节点。

image-20221018211929347

  • 一个节点系列 k 1 , k 2 , … … , k i , k i + 1 , … … , k j , k1,k2, ……,ki,ki+1, ……,kj, k1,k2,……,ki,ki+1,……,kj,并满足 k i ki ki k i + 1 ki+1 ki+1的父节点,就称为一条从 k 1 k1 k1 k j kj kj路径
  • 路径的长度为 j − 1 j-1 j1,即路径中的边数
  • 路径中前面的节点是后面节点的祖先,后面节点是前面节点的子孙
  • 节点的层数等于父节点的层数加一,根节点的层数定义为一。树中节点层数的最大值称为该树的高度或深度

image-20221018212203768

  • 若树中每个节点的各个子树的排列为从左到右,不能交换,即兄弟之间是有序的,则该树称为有序树
  • m(m≥0)棵互不相交的树的集合称为森林
  • 树去掉根节点就成为森林,森林加上一个新的根节点就成为树。

树的逻辑结构 :树中任何节点都可以有零个或多个直接后继节点(子节点),但至多只有一个直接前趋节点(父节点),根节点没有前趋节点,叶节点没有后继节点。

二叉树的原理

二叉树的概念

二叉树是n(n≥0)个节点的有限集合

或者是空集(n=0)

或者是由一个根节点以及两棵互不相交的、分别称为左子树和右子树的二叉树组成.

严格区分左孩子和右孩子,即使只有一个子节点也要区分左右。

二叉树的性质

  • 二叉树第i(i≥1)层上的节点最多为2i-1个。
  • 深度为k(k≥1)的二叉树最多有2k-1个节点。

满二叉树 :深度为k(k≥1)时有2k-1个节点的二叉树。

完全二叉树 :只有最下面两层有度数小于2的节点,且最下面一层的叶节点集中在最左边的若干位置上。

具有n个节点的完全二叉树的深度为 ( l o g 2 n )+ 1 或『 l o g 2 ( n + 1 ) (log2n)+1或『log2(n+1) log2n)+1或『log2(n+1)

二叉树顺序存储

顺序存储结构 :完全二叉树节点的编号方法是从上到下,从左到右,根节点为1号节点。设完全二叉树的节点数为n,某节点编号为i

当i>1(不是根节点)时,有父节点,其编号为i/2;

当2i≤n时,有左孩子,其编号为2i ,否则没有左孩子,本身是叶节点;

当2i+1≤n时,有右孩子,其编号为2i+1 ,否则没有右孩子;

当i为奇数且不为1时,有左兄弟,其编号为i-1,否则没有左兄弟;

当i为偶数且小于n时,有右兄弟,其编号为i+1,否则没有右兄弟;

image-20221019010528630

**存储空间浪费:**有n个节点的完全二叉树可以用有n+1个元素的数组进行顺序存储,节点号和数组下标一一对应,下标为零的元素不用。

利用以上特性,可以从下标获得节点的逻辑关系。不完全二叉树通过添加虚节点构成完全二叉树,然后用数组存储,这要浪费一些存储空间。

image-20221019010709267

二叉树链式存储

二叉树由根节点指针决定。

typedef int data_t ; 

typedef struct node_t; 

{
 data_t data ;  
 struct node_t *left ,*right;  
} bitree_t ;  

bitree_t *root ;  //二叉树由根节点指针决定。 

image-20221019010839987

二叉树的实现

二叉树的遍历

由于二叉树的递归性质,遍历算法也是递归的。三种基本的遍历算法如下 :

  • 先序遍历:先访问树根,再访问左子树,最后访问右子树;
  • 中序遍历:先访问左子树,再访问树根,最后访问右子树;
  • 后序遍历:先访问左子树,再访问右子树,最后访问树根

创建树

先序遍历的方式创建树

bitree * tree_create() {
	data_t ch;
	bitree *r;

    scanf("%c", &ch);
    if (ch == '#')
        return NULL;

    if ((r = (bitree *)malloc(sizeof(bitree))) == NULL) {
        printf("malloc failed\n");
        return NULL;
    }
    r->data = ch;
    r->left  = tree_create(); 
    r->right = tree_create(); 
    return r;
}

先序遍历

void preorder(bitree * r) {
	if (r == NULL) {
		return;
	}
	printf("%c", r->data);
	preorder(r->left);
	preorder(r->right);
}

中序遍历

void inorder(bitree * r) {
	if (r == NULL) {
		return;
	}
	inorder(r->left);
	printf("%c", r->data);
	inorder(r->right);
}

后序遍历

void postorder(bitree * r) {
	if (r == NULL) {
		return;
	}
	postorder(r->left);
	postorder(r->right);
	printf("%c", r->data);
}

}


### 后序遍历

```c
void postorder(bitree * r) {
	if (r == NULL) {
		return;
	}
	postorder(r->left);
	postorder(r->right);
	printf("%c", r->data);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深センのHZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值