(一)树与二叉树的基础理论
一、基本术语
用一些通俗的话说明
- 结点:图中一个圈就是一个结点
- 结点的度:结点下的分支数,比如 A 结点的度为3
- 叶子结点 (终端结点):图中最底下的结点,度为0,没有分支
- 分支结点 (非终端结点):度不为0的结点,和 叶子结点 (终端结点)相反
- 树的度:Max(各结点的度)
- 子树:图中 A 有三条子树 : 它们的根分别是 B、C、D 结点
- 双亲、孩子:分支的两端,上面是双亲,下面是孩子,比如 A 结点是 B、C、D 结点的双亲,反之,B、C、D 结点是 A 结点的孩子
- 兄弟:同一个双亲的孩子互称兄弟,比如 B、C、D 结点
- 堂兄弟:G 和 E、F、H、I、J
- 祖先:直系,比如 M 结点的祖先是 H、D 或 A 结点
- 子孙:以某节点为根的子树中任一结点都称为该结点的子孙,比如 B 的子孙有:E、F、K、L
- 深度:就是看树有几层,图中树有 4 层,即深度为 4
- 高度:从下往上数,看有几层,有些资料把首层称为0,有些称为1
关于
结点
和节点
:用的顺手就好在
严蔚敏《数据结构》书 P120
中,高度和深度为同一概念,本人认为应该区分开
二、树和二叉树的定义(特点)
书本上的定义有时候让人摸不着头脑,下面是我的理解
-
树:形如左图所示,可以想像成一棵倒着的树(不过说成一串葡萄可能更合理吧,哈哈)
特点:
(1)有且只有一个根(2)子树没有交集
-
二叉树:形如右图所示,是一种特殊的树
特点:
(1)每个结点最多有两棵子树,度<=2(2)子树有左右之分,是有序树
三、二叉树的性质和解释
二叉树的性质是重点!!!
性质1:在第 i 层最多有 2i-1 个结点( i 为正整数)
性质2:深度为 k 的二叉树最多有 2k-1 个结点
性质3:度为0的节点数 = 度为2的节点数+1 即 n0 = n2 +1
证明了解更好
性质1—归纳法证明 书P123
性质2—首项 a1 = 1 ,公比为 q = 2 ,项数 n = k 的等比数列求和问题:等比数列求和公式 Sn=a1*(1-qn)/(1-q)
关于性质3的两种说明:
四、满二叉树和完全二叉树
- 满二叉树:所有层数结点数都是满的,假设该二叉树有 k 层,则结点个数有 2k-1个(性质2)
- 完全二叉树:在满二叉树的基础上在最深层右边连续地减掉一些结点,比如上图减掉 13、14、15 结点所形成的完全二叉树
五、二叉树的存储结构
5.1 顺序存储结构
不是重点,一般用链式存储结构
将一般二叉树转换为满二叉树,顺序映射到一维数组上,如果二叉树比较空,顺序储存结构比较费空间
#include <iostream>
#include <cmath>
using namespace std;
const int MAX_NODE_SIZE = 127; // 2^7 - 1 = 128, 7层
class SqBiTree
{
//private:
public:
int m_SqBiTree[MAX_NODE_SIZE]; //0号元素存储根节点
int m_order;//完全满二叉树的层数
public:
void Print()
{
if(this->m_order<=0) return;
cout << "第1层:" << this->m_SqBiTree[0] << endl;
for(int i=2; i<=m_order; i++)
{
cout << "第" << i << "层:";
for(int j= pow(2,i-1)-1; j<=pow(2,i)-2; j++)
{
cout << this->m_SqBiTree[j] << " ";
}
cout << endl;
}
}
};
int main()
{
int last = 14;
SqBiTree bt;
for(int i=0; i<=last; i++)
{
bt.m_SqBiTree[i] = i;
}
bt.m_order = ceil(log2(last+2));
bt.Print();
// cout << ceil(log2(last+2)) << endl;
return 0;
}
5.2 链式存储结构
二叉链表和三叉链表的区别是指针域有无指向双亲的指针
-
二叉链表节点结构体定义
struct Node{ //数据域 int date; //指针域 Node* left; Node* right; //Node* parent;//没有指向双亲的指针 //构造函数 Node(int v):date(v),left(NULL),right(NULL){}; };
-
三叉链表节点结构体定义
struct Node{ //数据域 int date; //指针域 Node* left; Node* right; Node* parent; //构造函数 Node(int v):date(v),left(NULL),right(NULL),parent(NULL){}; };