树
🎈1.树和二叉树
🎈2.树
🔭2.1树的定义
🔭2.2树的4种表示方法
🔭2.3树的基本术语
- 结点:树中每个元素对应一个结点。每个结点包含一个数据元素及若干指向子树的分支。例如,图中的树有11个结点,结点D包含3个分支。
- 结点的度:结点所拥有的子树的个数称为结点的度。例如,结点A和D的度均为3,结点B的度为2,结点C的度为1,结点F的度为0。
- 叶子结点:度为0的结点称为叶子结点(或称树叶),又称终端结点。例如,上图所示,E,F,G,H,I,K都是叶子结点。
- 分支结点:度不为0的结点称为分支结点,又称非终端结点。例如,上图所示的树,A,B,C,D,J都是分支结点。
- 树的度:树中所有结点的最大度数称为树的度。例如,图所示的树的度为3.
- 双亲结点:若结点X有孩子,则X为孩子的双亲结点,简称双亲。例如,在图所示的树中,结点H,I,J的双亲是D,根结点A没有双亲,树中只有根结点没有双亲。
- 孩子结点:若结点X由子树,则子树的根结点即为结点X的孩子结点,简称孩子。例如,结点D有三个孩子H,I,J。
- 兄弟结点:同一双亲的孩子结点称为兄弟结点,简称兄弟。例如,结点H,I,J为兄弟。
- 堂兄弟结点:在树中的层次相同,但双亲不同的结点称为堂兄弟,简称堂兄。例如,结点F,G,H为堂兄弟。
- 祖先结点:从根结点到结点X所经过分支上的所有结点,都称为X的祖先结点,简称祖先。例如,K的祖先为A,D,J
- 子孙结点:结点X的孩子,以及这些孩子的孩子都是X的子孙结点。例如,结点D的子孙为H,I,J,K
- 结点的层次:根结点的层次为1,根结点的孩子的层次为2,根结点的孩子的孩子的层次为3,依次类推。
- 树的深度:树中结点的最大层次称为树的深度,也称树高。空树的深度为0,只有一个根结点的树的深度为1,图所示的树的深度为4.
- 路径:从树的某个结点X到其子孙结点Y所经过的路线叫做路径,路径上经过的边的数称为路径长度。由于树中无回路,所以树的路径是唯一的。如图所示的树中,从A到结点K的路径是A,D,J,K,路径长度为3.
- 森林:m(m>=)棵互不相交的树构成的集合称之为森林。
🔭2.4树的抽象数据类型定义
ADT Tree{
数据对象D:D为性质相同的数据元素的集合
数据关系R:
若D为空集,则称为空树。
若D仅有一个数据元素,则R=空集,否则R!=空集。
(1).在D中存在唯一的称为根的数据元素root,它在关系R下无前驱。
(2).存在D-{root}的一个划分{D1,D2,...,Dm}(m>0),且对于(1<=i<=m),存在唯一的数据元素Xi属于Di,有(root,Xi)属于R.
(3).对应于D-{root}的一个划分,r-{(root,x1),(root,x2),...,(root,Xm)}存在唯一的一个划分{R1,R2,...,Rm}(m>0),对于(1<=i<=m),Ri是Di上的二元关系,(xi,Ri)(i=1,2,...,m)是一棵符合本定义的树,称为根root的子树。
基本操作:
InitTree(&t):构造一棵空树
DestroyTree(&t):销毁一棵树
Parent(t,e):求结点e的双亲结点
Sons(t,e):求结点e有所有孩子结点
LeftChild(t,e):返回结点e的右兄弟最左孩子
RightSibling(t,e):返回结点e的右兄弟结点
TraraverseTree(t,visit()):以visit()函数访问树中每个结点
DepthTree(t):返回树的深度
}ADT Tree
🎈3.二叉树
🔭3.1二叉树的定义
🔭3.2二叉树的抽象数据类型定义
🔭3.3满二叉树
🔭3.4完全二叉树
🔭3.5完全二叉树的特点
- 叶子结点只能在第
k
层和第k-1
层上出现。 - 对于任意结点,若其右子树的深度为
l
,则其左子树的深度为l
或l+1
。 - 度为
1
的结点数为0或1
。当结点的总数为奇数
时,度为1
的结点数为0
,当结点的总数为偶数
时,度为1
的结点数为1
.
🔭3.6二叉树的性质
- 二叉树的第
i
层上至多有2i-1(i>=1)个结点。 - 深度为
k
的二叉树最多有2k-1(k>=1)个结点。 - 对于任何一棵二叉树,如果其叶子结点数为
n0
,度为2
的结点数为n2
,则n0=n2+1.
性质3推论:对于任何一棵k
叉树,如果叶子结点数为n0
,度为1,2,...k
的结点数分别为n1,n2,...,nk
,则n0=n2+2n3+3n4+...(k-1)nk+1
.
- 一棵具有n个结点的完全二叉树的深度为[log2n]+1(以2为底,n的对数)。
🔭3.7二叉树的存储结构
📝二叉树的顺序存储结构类型定义如下:
#define MaxSize 100 //二叉树的最大存储容量
typedef ElemType SqBiTree[MaxSize] //用数组存储二叉树的数据元素
SqBiTree bt;
🔭3.8完全二叉树的顺序存储
🔭3.9一般二叉树的存储结构
🔭3.10二叉树的链式存储结构
二叉链表的结点类型定义:
typedef struct BitNode
{
ElemType data;//数据元素信息
BitNode *lchild;//指向左孩子结点
BitNode *rchild;//指向右孩子结点
}BitNode;
🎈4.二叉树的类定义及其实现
🔭4.1二叉树的类定义
#include <iostream>
using namespace std;
typedef struct BitNode
{
char data;
BitNode* lchild;
BitNode* rchild;
}BitNode;
class BiTree
{
private:
BitNode* bt;
void Rcreate(BitNode*& t);//递归创建二叉树
void PreTraverse(BitNode* t);//先序遍历递归函数
void InTraverse(BitNode* t);//中序遍历递归函数
void PostTraverse(BitNode* t);//后序遍历递归函数
int BTNodeDepth(BitNode* t);//计算二叉树的树高递归函数
int BTNodeLeaf(BitNode* t);//计算二叉树树叶数递归函数
BitNode* SearchNode(BitNode* t, char x);//查找值等于x的结点递归函数
public:
BiTree()
{
bt = NULL;//创建空树
}
void RcreateBiTree();//创建二叉树
void PreTraverseBiTree();//先序遍历二叉树
void InTraverse();//中序遍历二叉树
void PostTraverse();//后序遍历二叉树
int BTNodeDepthBiTree();//计算二叉树的树高
int BTNodeLeafBiTree();//计算二叉树的叶子数
BitNode* SearchNodeBit(char x);//查找值等于x的结点
};
🔭4.2二叉树的实现
📖4.2.1创建二叉树
void BiTree::Rcreate(BitNode*& t)
{
char ch;
cin >> ch;
if (ch == '.')
t = NULL;
else
{
t = new BitNode;//申请空间
t->data = ch;
Rcreate(t->lchild);//递归创建左子树
Rcreate(t->rchild);//递归创建右子树
}
}
void BiTree::RcreateBiTree()
{
BitNode* t;
Rcreate(t);//递归创建二叉树
bt = t;//将根结点指针赋值给私有成员bt
}
📖4.2.2计算二叉树的高度
int BiTree::BTNodeDepth(BitNode* t)
{
if (t == NULL)
return 0;
else
{
int m = 1 + BTNodeDepth(t->lchild);//计算左子树树高度
int n = 1 + BTNodeDepth(t->rchild);//计算右子树树高度
if (m >= n)//比较左右子树高度
return m;
else
return n;
}
}
int BiTree::BTNodeDepthBiTree()
{
//计算二叉树的高度
BitNode* p = bt;
return BTNodeDepth(p);//调用计算二叉树高度的递归函数
}
📖4.2.3计算二叉树的树叶数
int BiTree::BTNodeLeaf(BitNode* t)
{
//递归算法计算二叉树的树叶数
if (t == NULL)
return 0;
else
{
int m = BTNodeLeaf(t->lchild);
//计算左子树的树叶数
int n = BTNodeLeaf(t->rchild);
//计算右子树的树叶数
if (m + n == 0)
return 1;
else
return m + n;
}
}
int BiTree::BTNodeLeafBiTree()
{
//计算二叉树的树叶数
BitNode* p = bt;//读取私有成员指针bt
return BTNodeLeaf(p);//调用二叉树的树叶数的递归函数
}
📖4.2.4查找二叉树
BitNode* BiTree::SearchNode(BitNode* t, char x)
{
BitNode* p;
if (t == NULL)
return NULL;
if (t->data == x)
return t;
else
{
p = SearchNode(t->lchild,x);//递归查找左子树
if (p != NULL)
return p;
else
return SearchNode(t->rchild, x);//递归查找右子树
}
}
BitNode* BiTree::SearchNodeBit(char x)
{
BitNode* p = bt;
return SearchNode(p, x);
}