5.2.1二叉树的定义
二叉树特点:
①每个节点最多只有两颗子树
②二叉树的子树有左右之分,不能随意颠倒
③二叉树为有序树
几种特殊的二叉树
- 满二叉树
除叶节点之外的每个节点度数均为2
对于编号i的节点,若有双亲,则双亲为i/2-向下取整
若有左孩子,则为2i;若有右孩子则为2i+1
- 完全二叉树
当且仅当每个节点斗鱼高度为h的满二叉树1~n的节点一一对应,则为完全二叉树
特点:
①i<=n/2-->分支节点;i>n/2-->叶子节点
②叶节点出现位置:层次最大的两层上,都在该层最左边的位置
③若n为奇数,则每个节点都有左孩子,右孩子;若为偶函数,则编号最大的分支节点(n/2)只有左孩子,没有右孩子
二叉排序树,平衡二叉树,正则二叉树--后面讲的
二叉树的性质
- 叶节点数=2的节点数+1
- 第k层最多有(2^k-1)个节点
- 高度为h的二叉树至多有(2^h)-1个节点
5.2.2二叉树的存储结构
1.顺序存储结构
只用于存储完全二叉树和满二叉树
定义长度为MaxSize的数组t,按照从上到下,从左至右的顺序依次存储完全二叉树中的各个节点
代码
#include<stdio.h>
#define MaxSize 100
//顺序存储二叉树
struct treeNode{
int data;//数据
bool isEmpt;//是否存储
};
void init(treeNode* t) {
for (int i = 0; i < MaxSize; i++)
{
t[i].isEmpt = true;
}
}
基本操作:
to非完全二叉树
会有大量内存闲置浪费,一个长度为h,且只有h个节点的单支树需要接近(2^h-1)个存储单元
2.链式存储结构
二叉树一般采用链式存储,因为顺序存储效率低
- n个节点的二叉链表共有n+1个空链域;
链表中有n个元素,有2n个指针,除头节点外,每个节点都会有一个指针指向,所以有n-1个指针在发挥作用,则空指针即空链域有n+1个;
- 链式存储结构代码
节点结构体
#include<stdio.h>
#include <malloc.h>
typedef struct BitNode
{
int data;//数据
BitNode* lChild;//左孩子
BitNode* rChild;//右孩子
}BitNode,*linklist;
初始化根节点
void init(linklist r) {
//插入根节点
r->data = 1;
r->lChild = NULL;
r->rChild = NULL;
}
插入第一个节点元素
void add(linklist r) {
//根节点后插入新节点
//定义新节点
linklist p=(linklist)malloc(sizeof(BitNode));
p->data = 2;
p->lChild = NULL;
p->rChild = NULL;
r->lChild = p;
}
- 三叉链表
二叉链表找到左孩子,右孩子很检点,但找父节点只能从根开始遍历 ,所以在定义结构体时加入父节点指针
typedef struct Node
{
int data;//数据
Node* lChild;//左孩子
Node* rChild;//右孩子
Node* parent;//指向父节点;
}Node, * linklist1;