#二叉树(binary)
二叉树就是节点的度不大于2的树,即树中每个节点的子节点最多只有两个。每个节点的子节点分为左子节点和右子节点,并且左右子节点的顺序不能改变。
1. 二叉树分类
二叉树分为满二叉树、完全二叉树和完美二叉树。
1.1满二叉树(full binary tree)
满二叉树是除了叶子节点外,每个节点都有两个子节点的树。
如下图所示的两棵树,左边的树是满二叉树,因为除了叶子节点以外,每个节点都有两个子节点。但是右边的不是满二叉树,因为除了叶子节点以外,第二层的第一个节点只有一个子节点。
1.2 完全二叉树(complete binary tree)
完全二叉树除了最后一层节点以外,其余的节点形成一个满二叉树,并且最后一层节点从左往右依次填满,没有空出来的节点。
1.3 完美二叉树(perfect binary tree)
完美二叉树的叶子节点在同一层,并且所有的内部节点都有两个子节点。
使用下面的图更好的区分这几个概念
2. 二叉树的存储
同堆栈一样,二叉树的实现也可以采用数组和链表形式实现。
2.1 数组形式
二叉树的数组存储形式其实就是层级遍历的结果:从一层逐层往下遍历,每层从左往右遍历。假设一个节点在数组中的下标为i,则其左子节点的下标为2*i, 右子节点的下标为2*i+1,其父节点的下标为\lfloor\frac{i}{2}} \rfloor N
假设有如下二叉树,则其数组存储结果为:
2.2 链式形式
二叉树的链式存储结构中,将每个节点封装成一个结构体,存储节点的值以及两个分别指向左右子节点的指针。叶子节点的左右子节点指针都为空指针。
typedef struct node
{
int val;
struct node *left;
struct node *right;
}Node;
3. 二叉树查找树及其基本操作
下面使用链式存储形式说明二叉树的相关操作。
通常我们建立一棵树,自然是希望这棵树能够表示一定的意义方便找到需要的元素或进行相关操作,所以建立的二叉树都不是无意义的。现在建立一棵树使得每个节点左边节点的值都小于它,右边的节点的值都大于它。(有时候可能需要记录每个数据元素,为了保留相同的元素有两种方法:1. 约定每个节点的左边节点的值小于等于这个节点的值,右边节点的值都大于这个节点的值。这种方法十分直观,但是会造成空间浪费; 2. 约定每个节点左边节点的值都小于它,右边的节点的值都大于它,使用一个计数器记录有多少个与当前节点值相同的元素。这里只考虑最简单的情况,即没有重复的元素)这样得到的二叉树叫做二叉查找树(Binary Search Tree,也叫作二叉搜索树)。
3.1 查找
查找的过程如下:
1. 如果二叉树为空树,查找失败,返回NULL
2. 如果key等于根节点的值,则查找成功,返回root
3. 如果key小于根节点的值,递归查找左子树
4. 如果key大于根