二叉树部分面试题
在这里做一些补充。
九、求二叉树的镜像
二叉树的镜像树就是把一个节点下的左右孩子交换,例如:
这样与层序遍历还有些相似,实现如下:
递归
//求二叉树的镜像
PNode _MirrorBinTree1(PNode pRoot)
{
if (pRoot == NULL)
return 0;
swap(pRoot->_left, pRoot->_right);
_MirrorBinTree1(pRoot->_left);
_MirrorBinTree1(pRoot->_right);
return pRoot;
}
非递归
//求二叉树的镜像
PNode _MirrorBinTree2(PNode pRoot)
{
if (pRoot == NULL)
return 0;
queue q;
q.push(pRoot);
while (!q.empty())
{
PNode front = q.front();
swap(front->_left, front->_right);
q.pop();
if (front->_left)
q.push(front->_left);
if (front->_right)
q.push(front->_right);
}
}
十、判断二叉树是否为完全二叉树
完全二叉树的概念文章开始已经讲过。二叉树可分为空树,只有一个节点,多个节点。而多个节点可分为以下方面:
1、左右子树均存在
2、只有左,没有右
3、只有右,没有左(false)
4、没有左右子树
我们利用队列实现,如下:
代码如下:
bool _CompleteBinTree(PNode pRoot)
{
if (pRoot == NULL)
return 1;
if (pRoot->_left == NULL && pRoot->_right == NULL)
return 0;
queue q;
q.push(pRoot);
bool flag = false;
while (!q.empty())
{
PNode pCur = q.front();
q.pop();
if (pCur->_left == NULL || pCur->_right == NULL)
{
if (pCur->_left == NULL&&pCur->_right != NULL)
{
q.push(pCur->_left);
flag = true;
}
else if (pCur->_right == NULL&&pCur->_left != NULL)
{
flag = false;
}
else
flag = true;
}
else
{
q.push(pCur->_left);
q.push(pCur->_right);
}
}
return flag;
}
测试:
template
struct TreeNode
{
T _data;
TreeNode *_left;
TreeNode *_right;
TreeNode(const T& data)
:_data(data)
, _left(NULL)
, _right(NULL)
{}
};
template
class BinTree
{
typedef TreeNode Node;
typedef TreeNode *PNode;
public:
BinTree()
: _pRoot(NULL)
{}
BinTree(const T* array, size_t size, const T& invalid)
{
size_t index = 0;
_pRoot = _CreateBinTree(array, size, index, invalid);
}
BinTree(const BinTree& bt)
{
_pRoot = _CopyBinTree(bt._pRoot);
}
BinTree& operator=(const BinTree& bt)
{
if (this == bt)
return;
_DestroyBinTree(_pRoot);
_pRoot = new Node(bt->_data);
_pRoot->_left = bt->_left;
_pRoot->_right = bt->_right;
}
~BinTree()
{
_DestroyBinTree(_pRoot);
}
void PreOrder()
{
_PreOrder1(_pRoot);
cout << endl;
}
PNode MirrorBinTree1()
{
return _MirrorBinTree1(_pRoot);
}
PNode MirrorBinTree2()
{
return _MirrorBinTree2(_pRoot);
}
bool CompleteBinTree()
{
return _CompleteBinTree(_pRoot);
}
private:
//求二叉树的镜像
PNode _MirrorBinTree1(PNode pRoot)
{
if (pRoot == NULL)
return 0;
swap(pRoot->_left, pRoot->_right);
_MirrorBinTree1(pRoot->_left);
_MirrorBinTree1(pRoot->_right);
return pRoot;
}
//求二叉树的镜像
PNode _MirrorBinTree2(PNode pRoot)
{
if (pRoot == NULL)
return 0;
queue q;
q.push(pRoot);
while (!q.empty())
{
PNode front = q.front();
swap(front->_left, front->_right);
q.pop();
if (front->_left)
q.push(front->_left);
if (front->_right)
q.push(front->_right);
}
}
//判断完全二叉树
bool _CompleteBinTree(PNode pRoot)
{
if (pRoot == NULL)
return 1;
if (pRoot->_left == NULL && pRoot->_right == NULL)
return 0;
queue q;
q.push(pRoot);
bool flag = false;
while (!q.empty())
{
PNode pCur = q.front();
q.pop();
if (pCur->_left == NULL || pCur->_right == NULL)
{
if (pCur->_left == NULL&&pCur->_right != NULL)
{
q.push(pCur->_left);
flag = true;
}
else if (pCur->_right == NULL&&pCur->_left != NULL)
{
flag = false;
}
else
flag = true;
}
else
{
q.push(pCur->_left);
q.push(pCur->_right);
}
}
return flag;
}
private:
PNode _pRoot;
};
测试:
int main()
{
//完全二叉树
char array1[] = "abc##d##ef##g";
BinTree bt1(array1,strlen(array1),'#');
//不完全二叉树
char array2[] = "abc###def##g";
BinTree bt2(array2, strlen(array2), '#');
bt1.PreOrder();
bt1.MirrorBinTree1();
bt1.MirrorBinTree2();
bt1.PreOrder();
cout << bt1.CompleteBinTree() << endl;
cout << bt2.CompleteBinTree() << endl;
system("pause");
return 0;
}
两次镜像应该返回原样,测试结果: