第三讲树

基本知识

定义
树是n(n >= 0)个结点的有限集合。n = 0时称为空树。在任意一棵非空树:

  1. 有且仅有一个特定的称为根的结点;
  2. 当n > 1时,其余结点可分为m(m > 0)个互不相交的有限集T1 、T2 、 … 、Tm,其中每一个集合本身又是一棵树,并且称为子树。
    在这里插入图片描述
    在这里插入图片描述
    补充:
    1.某个(或多个)结点它的子结点数量最多,则这个数量称作这棵树的度;
    2.一棵树的层数称作此树的 深度或高度

重要类型:二叉树

1.一般的树双亲结点下可以连很多子结点,但是二叉树最多连接两个子结点
2.二叉树 左右子树 顺序是不能颠倒的,画的时候不能都放在同一侧
3.由于第2点,即使只有一颗子树,都能很清楚的知道它是左子树还是右子树

斜树
二叉树完全往一个方向斜(只有左孩子或者右孩子),且每一层只有一个结点结点数 = 层数 = 深度
如:
在这里插入图片描述
满二叉树
所有叶结点存在于同一层,且除了这些叶结点外,其他结点都存在左右子树
如:
在这里插入图片描述
给上面结点编号是为了引出下面这种二叉树
完全二叉树
n 个 结点的二叉树按层次序编号(一层一层来,每层从左到右),如 (4 个 结点的 1 ~ 4),与 同样深度满二叉树编号为 i结点位置完全相同,则次二叉树为完全二叉树
如:
在这里插入图片描述
可以很明显的看出:完全二叉树可以由满二叉树去掉一部分得来。

1. 满二叉树一定是完全二叉树
2. 完全二叉树不一定是满二叉树

3. 可以理解成满二叉树是一种特殊的完全二叉树

二叉树性质
1 在二叉树第 i 层上至多有 2 ^i - 1 个结点(i >= 1
2 深度为 k 的二叉树至多有 2 ^ k - 1 个结点(k >= 1
3 任何一颗二叉树 T ,如果其终端结点数为 n0,度为 2 的结点数为 n2n0 = n2 + 1
4 具有 n 个结点的完全二叉树的 深度为【log2 n】 + 1【x】表示不大于 x 的最大整数

二叉树的建立与存储
递归方法更好
一般是这样出现要求你建立:

ABC##DE#G##F###

struct node
{
	int data;
	struct node*l;
	struct node*r;	
};

struct node*creat()
{
	struct node*head;
	int ch = a[i++];
	
	head = (struct node*)malloc(sizeof(struct node));
		
	if(ch == '#') // 一个字符一个字符输入,#则表示该结点为空
	{
		head = NULL;
	}
	else
	{
		head -> data = ch; // 不为空则存储数据
		head -> l = creat();
		head -> r = creat();
	}
	
	return head;
}

二叉树的遍历
1. 序遍历(根左右)从 左子树 再到 右子树
2. 序遍历(左根右)从 左子树 再到 右子树
3. 序遍历(左右根)从 左子树右子树 再到

先序:
在这里插入图片描述

void printx(struct node*head)
{
	if(head == NULL)
	{
		return;
	}
	
	printf("%c",head -> data);
	printx(head -> l);
	printx(head -> r);
	return;
}

中序:
在这里插入图片描述

void printz(struct node*head)
{
	if(head == NULL)
	{
		return;
	}
	
	printx(head -> l);
	printf("%c",head -> data);
	printx(head -> r);
	return;
}

后序:
在这里插入图片描述

void printh(struct node*head)
{
	if(head == NULL)
	{
		return;
	}
	
	printx(head -> l);
	printx(head -> r);
	printf("%c",head -> data);
	return;
}

遍历图片来源于http://www.pianshen.com/article/7106254596/侵删

可以很清楚的看到,前序 中序 后序 完全只是 输出的位置不同,而且符合其顺序规律

4.层次 序:最简单的遍历方法,一层一层来,每层都按从左到右

void printc(struct node*head)
{
	if(head == NULL)
	{
		return;
	}
	
	queue<struct node*>dl;
	struct node*front;
	dl.push(head);
	
	while(!dl.empty())
	{
		front = dl.front();
		dl.pop();
		
		if(front -> l)dl.push(front -> l);
		if(front -> r)dl.push(front -> r);
		printf("%c",front -> data);
	}
	return;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值