树的基本概念:
结点的度:结点子树的个数
叶子结点:度为0的结点
二叉树(Binary Tree):度为2的树
完美二叉树(Perfect BT \Full BT):
完全二叉树(Complete BT):
树的性质
二叉搜索树(BST,Binary Search Tree):
1.非空左子树的所有键值小于根;
2.非空右子树的所有键值大于根;
3.左、右子树都是BST;
完全二叉搜索树(CBST):
1.是完全二叉树;
2.是搜索树;
3.一组元素有唯一确定的CBST
建树算法思路:将该组元素从小到大排序存入数组,根节点值比左子树所有节点值大,比右子树所有节点值小,求得左子树元素个数N,则根值为数组第N+1个元素值。将数组除去第N+1个元素后分为两个数组,分别递归,求左右子树。
#include<stdio.h>
#include<stdlib.h>
#include<cmath>
#include<algorithm>
int getLeftTNodeNumber(const int n)//求左子树节点个数
{ int TreeH,Left;
for(TreeH=1;(std::pow(2,TreeH)-1)<=n;TreeH++);//求树的高度TreeH
Left=n-(std::pow(2,TreeH-1)-1);
if(Left<=std::pow(2,TreeH-1)/2)
return std::pow(2,TreeH-2)-1+Left;
else
return std::pow(2,TreeH-1)-1;//左子树满叶
}
// Tree 为指向CBST的指针
// SortedDatas 为指向经过排序的数组的指针
// leftPos,rightPos 分别为该次搜寻根节点的数组范围上、下下标
// RootPos 为该次根节点在 Tree中的位置
void creatCBST(int * Tree,const int* SortedDatas,const int leftPos,const int rightPos,const int RootPos)
{
int n = rightPos-leftPos +1;//该次 节点总个数
if(n==0)
return;
int leftTreeNodeNumber=getLeftTNodeNumber(n);//左子树节点个数
*(Tree+RootPos)=*(SortedDatas+leftPos+leftTreeNodeNumber);//顺序数组SortedDatas的[leftPos,rightPos]中的第leftTreeNodeNumber+1个为根节点
creatCBST(Tree,SortedDatas,leftPos,leftPos+leftTreeNodeNumber-1,RootPos*2+1);//左子树
creatCBST(Tree,SortedDatas,leftPos+leftTreeNodeNumber+1,rightPos,RootPos*2+2);//右子树
}
int* bulitCBST(const unsigned int NodeNumber,int* datas)
{
if(NodeNumber==1)
return datas;
std::sort(datas,datas+NodeNumber);//将datas 数组排序
int* Tree=new int[NodeNumber];
creatCBST(Tree,datas,0,NodeNumber-1,0);
return Tree;
}
int main(){
int NodeNumber;
scanf("%d",&NodeNumber);
int* data=new int[NodeNumber];
for(int i=0;i<NodeNumber;i++)
{
scanf("%d",data+i);
}
int* ptrTree=bulitCBST(NodeNumber,data);
for(int i=0;i<NodeNumber;i++)
{
if(i!=(NodeNumber-1))
printf("%d ",*(ptrTree+i));
else
printf("%d",*(ptrTree+i));
}
return 0;
}
平衡二叉树(Balance BT):
是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
树的遍历:
…
树的同构判定:
给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。
//使用结构体数组表示
template<typename dataType>
struct TreeNode{
dataType data;
int leftTree;//使用数组下标表示,-1表示空结点
int rightTree;
};
//使用递归的方法判定树的同构
template<unsigned NodeNumber,typename TreeType>
bool isSimilar(const TreeType (&T1)[NodeNumber],const int T1NodePos,const TreeType(&T2)[NodeNumber],const int T2NodePos)
{
if(T1NodePos==-1 && T2NodePos==-1)//都是空树,则同构
return true;
else if(T1NodePos==-1 || T2NodePos==-1)//一个是空树,另一个不是空树,不同构
return false;
if(T1[T1NodePos].data==T2[T2NodePos].data)//结点数据相同
{
if(isSimilar(T1,T1[T1NodePos].leftTree,T2,T2[T2NodePos].leftTree) &&
isSimilar(T1,T1[T1NodePos].rightTree,T2,T2[T2NodePos].rightTree))
return true;//T1左子树与T2左子树同构,且T1右子树与T2右子树同构
else if(isSimilar(T1,T1[T1NodePos].leftTree,T2,T2[T2NodePos].rightTree) &&
isSimilar(T1,T1[T1NodePos].rightTree,T2,T2[T2NodePos].leftTree))
return true;//T1左子树与T2右子树同构,且T1右子树与T2左子树同
else
return false;
}
else//父结点数据不相同,不同构
return false;
}
堆
堆是一种完全二叉树,堆中某个节点的值总是不大于或不小于其父节点的值;将根节点最大的堆叫做最大堆、大根堆、大顶堆,根节点最小的堆叫做最小堆、小根堆、小顶堆。