二叉树的判别方法
只有左孩子和右孩子两个孩子
完全二叉树的判别算法
首先确定完全二叉树的根节点
对这棵树进行层序遍历,一边对二叉树进行BFS将每一个节点都加入到队列,一边执行下面的判断
当前节点有右孩子,但没有左孩子,直接返回false
当前节点有左孩子没右孩子,那么接下来遇到的所有节点必须是叶子节点
例如下图所示的情况,当遍历到红色节点后,由于其只有左孩子,没有右孩子,接下来的所有节点必须只能是叶子节点,如果不是,则该二叉树不是完全二叉树。例如,接下来访问到绿色节点,发现该节点不是叶子节点,因此直接返回false
bool IsFull(BinTree FBT)
{
queue<BinTree>que;
que.push(FBT);
bool state=false;
while(!que.empty());
{
BinTree temp=que.front();
que.pop(); //取出队列首元素并删除
BinTree l=temp->Left;
BinTree r=temp->Right;
if(l) que.push(l); //将首元素的左孩子压入队列中
if(r) que.push(r); //将首元素的右孩子压入队列中
if(!state) //后续结点均是叶子结点的状态还未开启
{
if(!l&&r) //该结点只有右孩子没有左孩子
return false;
if(l&&!r)
{
state=true;
}
}
else
{
if(l||r) //该结点不是叶子结点
return false;
}
}
}
大小根堆的判别算法
大根堆:对任意一个结点,均大于它的左孩子和右孩子
小根堆:对任意一个结点,均小于它的左孩子和右孩子
//大根堆即最大堆既是大根树也是完全二叉树,可用数组来存储
bool IsMin(Num num[],int n) //判断是否是最小堆,只需要满足任何一个结点都比左右结点小即可
{
for(int i=0;i<n;i++)
{
int l=num[i].Left; //左孩子
int r=num[i].Right; //右孩子
if(l!=-1)
{
if(num[i].k2>num[l].k2) return false;
}
if(r!=-1)
{
if(num[i].k2>num[r].k2) return false;
}
}
return true;
}
二插搜索树的判别算法
二叉搜索树:左子树所有节点均小于根节点,右子树所有节点均大于根节点,其左右子树也是二叉搜索树
方法一:对于每一个结点,大于其左孩子,小于其右孩子,并且左子树的最大值即结点左孩子的右孩子的右孩子的右孩子…小于该根结点,右子树的最小值即结点右孩子的左孩子的左孩子的左孩子…大于该根结点
bool IsBST(Num num[],int n)
{
for(int i=0;i<n;i++)
{
int l=num[i].Left; //左孩子
int r=num[i].Right; //右孩子
if(l!=-1)
{
if(num[i].k1<num[l].k1) return false;
int lmax=l;
while(num[lmax].Right!=-1)
{
lmax=num[lmax].Right;
}
if(num[lmax].k1>num[i].k1) //左子树的最大结点比根节点大,则满足二叉搜索树
return false;
}
if(r!=-1)
{
if(num[i].k1>num[r].k1) return false;
int rmin=r;
while(num[rmin].Left!=-1)
{
rmin=num[rmin].Left;
}
if(num[rmin].k1<num[i].k1) //右子树的最小结点比根节点小,则满足二叉搜索树
return false;
}
}
return true;
}
方法二:二叉搜索树中序遍历为递增序列
递归遍历中序序列时换成与前一个字符进行比较,若后一个字符小于前一个字符,则不是二叉搜索树;
AVL平衡二叉树判别算法
首先满足二叉搜索树
其次对于每一个结点,其平衡因子绝对值<=1(左子树高度减去右子树高度)