问题6:将二叉查找树变成有序的双向链表
要求不创建新节点,只调节指针
递归解法:
(1)如果二叉查找树为空,则不需要转换,双向链表的第一个节点为NULL,最后一个节点为NULL
(2)如果二叉查找树不为空,
如果左子树为空,则根节点为双向链表的第一个节点,左边不需要操作;
如果左子树不为空,转换左子树,则二叉查找树对应于双向链表的第一个节点就是转换成双向链表后的第一个节点,
同时将左子树转换成双向链表后的最后一个节点与根节点相连接。
如果右子树为空,则根节点为双向链表的最后一个节点,右边不需要操作;
如果右子树不为空,则二叉树对应于双向链表的最后一个节点就是转换成双向链表后的最后一个节点,
同时将根节点与右子树转换成双向链表后的第一个节点下一个连接
//pRoot为二叉查找树的根节点指针
//pFirstNode为转换成双向链表的第一个节点的指针
//pLastNode为转换成双向链表的最后一个节点的指针
void convert(BinaryTreeNode* pRoot,BinaryTreeNode* pFirstNode,BinaryTreeNode* pLastNode)
{
//左子树的第一个节点和最后一个节点,右子树的第一个节点和最后一个节点
BinaryTreeNode* pFirstLeft, *pLastLeft,*pFirstRight,*pLastRight;
if(pRoot==NULL)
{
pFirstNode=NULL;
pLastNode=NULL;
return;
}
if(pRoot->m_pLeft==NULL)
{
//左子树为空,对应有序双向链表的第一个节点为根节点
pFirstNode=pRoot;
}
else
{
convert(pRoot->m_pLeft,pFirstLeft,pLastLeft);
//二叉查找树对应有序双向链表的第一个节点就是左子树转换为有序双向链表的第一个节点
pFirstNode=pFirstLeft;
//将根节点与左子树转换成有序双向链表的第一个节点相连接。
pRoot->m_pLeft=pLastLeft;
pLastLeft->m_pRight=pRoot;
}
if(pRoot->m_pRight==NULL)
{
//如果右子树为空,对应有序双向链表的最后一个节点为根节点
pLastNode=pRoot;
}
else
{
convert(pRoot->m_pRight,pFirstRight,pLastRight);
//二叉查找树对应有序双向链表的最后一个节点就是右子树转换为双向链表后的最后一个节点
pLastNode=pLastRight;
//将根节点与右子树转换成有序双向链表的最后一个节点相连接
pRoot->m_pRight=pFirstRight;
pFirstRight->m_pLeft=pRoot;
}
return;
}
问题7:求二叉树第k层的节点个数
递归解法:
(1)如果二叉树为空或k<1;返回0;
(2)如果二叉树不为空,且k==1,返回1
(3)如果二叉树不为空,且k>1,则返回左子树k-1层的节点个数与右子树k-1层的节点个数之和
int GetLeafNodeNum(BinaryNode* pRoot)
{
if(pRoot==NULL)
return 0;
if(pRoot->m_pLeft==NULL && pRoot->m_pRight==NULL)
return 1;
int LeftNum=GetLeafNodeNum(pRoot->m_pLeft);//左子树叶子节点个数
int RightNum=GetLeafNodeNum(pRoot->m_pRight);//右子树节点个数
return (LeftNum+RightNum);
}
问题8:求二叉树中叶子节点的个数
递归解法:
(1)如果二叉树为空,返回0
(2)如果二叉树不为空,且左子树和右子树为空,返回1
(3)如果二叉树不为空,且的左子树和右子树不同时为空,则返回左子树和右子树叶子节点个数之和
int GetLeafNodeNum(BinaryNode* pRoot)
{
if(pRoot==NULL)
return 0;
if(pRoot->m_pLeft==NULL && pRoot->m_pRight==NULL)
return 1;
int LeftNum=GetLeafNodeNum(pRoot->m_pLeft);//左子树叶子节点个数
int RightNum=GetLeafNodeNum(pRoot->m_pRight);//右子树节点个数
return (LeftNum+RightNum);
}
问题9:判断两颗二叉树是不是结构相同
不考虑二叉树数据,二叉树结构相同意味着对应的左子树和右子树结构都相同
递归解法:
(1)如果两颗二叉树都为空,返回true
(2)如果两颗二叉树中一颗为空,另一个不为空则返回false
(3)如果两颗二叉树都不为空,对应的左子树和右子树结构相同返回真,其他返回假
bool StructCmp(BinaryTreeNode* pRoot1,BinaryTreeNode* pRoot2)
{
if(pRoot1==NULL && pRoot2==NULL)
return true;
if(pRoot1==NULL || pRoot2==NULL) //两颗二叉树中有一颗为空,返回假
return false;
bool LeftCmp=StructCmp(pRoot1->m_pLeft,pRoot2->m_pLeft);//比较对应左子树
bool RightCmp=StructCmp(pRoot1->m_pRight,pRoot2->m_pRight);//比较对应右子树
return LeftCmp&& RightCmp;
}
问题10:判断二叉树是不是平衡树(AVL)
递归解法:
(1)如果二叉树为空,返回真
(2)如果二叉树不为空,如果左子树和右子树都是AVL,且左子树与右子树深度差不超过1,则返回真,其他返回假。
bool IsAVL(BinaryTreeNode* pRoot,int & height)
{
if(pRoot==NULL)
{
height=0;
return true;
}
int heightLeft;
bool resultLeft=IsAVL(pRoot->m_pLeft,heightLeft);
int heightRight;
bool resultRight=IsAVL(pRoot->m_pRight,heightRight);
if(resultLeft && ResultRight && abs(heightLeft-heightRight)<=1)//左右子树都是AVL,且高度差不超过1
{
height=max(heightLeft,heightRight)+1;
return true;
}
else
{
height=max(heightLeft,heightRight)+1;
return false;
}
}