由一个或多个节点组成的有限集合。每一颗树必须有一个特定节点,叫做根节点。根节点下可以有零个以上的子节点。而且各子节点也可以为子树,拥有自己的子节点。
若一棵树中的节点最多可以有n个节点,则称该树为n元树。
n 树的相关名称
u 根节点(root node):树中没有父节点的节点即为根节点
u 叶节点(leaf node):没有子节点的节点
u 非叶节点:叶节点以外的节点
u 父节点(parent)和子节点(child)
u 兄弟节点(sibling):同一个父节点的节点
u 分支度(degree):每个节点所拥有的子节点个数,树中的最大的分支度值即为该树的分支度
u 阶层(level):根节点的阶层为1,其子节点为2,依次类推
u 高度和深度:树的最大阶层值即为树的高度或深度
u 祖先(ancestor):由某子节点到根节点的路径上的所有节点,均称为该节点的祖先
n 二叉树
树的一种,节点最多只能有两个节点
u 由有限个节点组成的集合,集合可以为空
u 根节点下可有两个子树,为左子树和右子树
n 二叉树与树的区别:
n 二叉树可以为空,而树不可以(至少要有根节点)
n 二叉树的子树有顺序关系
n 二叉树的分支度必须为0、1或2,而树的分支度可以大于2
n 二叉树类型:
n 左(右)歪斜树
u 所有节点的左子树均不存在,则此二叉树为右歪斜树
u 反之,则称之为左歪斜树。
n 满二叉树
u 所有叶节点均在同一阶层,其他非叶节点的分支度为2
u 若此树的高度为n,则该树的节点数为2^n - 1.
n 完全二叉树
u 一个二叉树除掉最大阶层后为满二叉树,且最大阶层的节点均向左靠齐。
n 二叉树的节点插入规则:
u 均转换成满二叉树的形式来插入节点数据。
u 对各阶层的节点由低阶层到高阶层,从左至右,由1开始编号,再根据编号将节点数据存入相应索引编号的数组(链表)中
u 如果某编号没有节点存在,则数组对应位置没有值存入。
u 插入的第一个元素为根节点
u 满足左小右大的二叉查找树规则
提问:依次输入数据6,3,8,5,2,9,4,7建立一个二叉树,请描述该二叉树节点的排列次序。
n 二叉树的三种表示法:
数组表示法
见例题。
优点:
查找容易且每个节点占用空间不大
缺点:
当二叉树的深度和节点数的比例偏高时,会造成空间浪费
数据的插入和删除涉及到移动大量数据的问题
节点数组表示法
包含三个数组:
一个数组存放节点数据内容
一个数组存放左子节点在数组中的下标
一个数组存放右子节点在数组中的下标
见例题
改良后的数组表示法,在插入和删除方面需移动的数据大大减少
链表表示法
在修改二叉树方面效率比数组实现高。
n 二叉树的遍历:
前序遍历(preorder traversal)
先遍历中间节点,再遍历左子树,最后遍历右子树
伪码表示:
If 指向根节点的指针 == null
Then 此为空树,遍历结束
Else
(1) 处理当前节点
(2) 往左走,递归处理preorder(root ' left)
(3) 往右走,递归处理preorder(root 'right)
中序遍历(inorder traversal)
先遍历左子树,再遍历中间节点,最后遍历右子树
伪码表示:
If 指向根节点的指针 == null
Then 此为空树,遍历结束
Else
(1)往左走,递归处理preorder(root ' left)
(2)处理当前节点
(3)往右走,递归处理preorder(root 'right)
后序遍历(postorder traversal)
先遍历左子树,再遍历右子树,最后遍历中间节点
伪码表示:
n 二叉树的查找:
先将二叉树转换成二叉查找树,即左小右大,接着可以采用二分查找方式来查找。
对二叉查找树的查找效率高于对非二叉查找树的查找
见例题。
n 二叉树的删除:
见例题。
分为几种情况:
1. 删除节点既无左子树也无右子树
l 根节点
l 非根节点
2. 删除节点有左子树,无右子树
3. 删除节点有右子树,无左子树
4. 删除节点既有左子树,也有右子树