判断一棵树是否为完全二叉树
2016-01-01 15:44
274 查看
问题:判断二叉树是否为完全二叉树。完全二叉树的定义是,前n-1层都是满的,第n层如有空缺,则是缺在右边,即第n层的最右边的节点,它的左边是满的,右边是空的。
以3层二叉树为例,以下情况为完全二叉树:
[方法一]
这个问题的描述已经提示了解法,采用广度优先遍历,从根节点开始,入队列,如果队列不为空,循环。遇到第一个没有左儿子或者右儿子的节点,设置标志位,如果之后再遇到有左/右儿子的节点,那么这不是一颗完全二叉树。
这个方法需要遍历整棵树,复杂度为O(N),N为节点的总数。
[cpp]
view plaincopy
//二叉树结点定义
typedef struct Node
{
int data;
struct Node* left;
struct Node* right;
}Node;
//实现广度遍历需要队列
Queue<Node*> queue;
//第n层最右节点标志
bool leftMost = false;
bool ProcessChild(Node* child)
{
if (child)
{
if (!leftMost)
{
queue.push(child);
}
else
{
return false;
}
}
else
{
leftMost = true;
}
return true;
}
bool IsCompleteBinaryTree(Node* root)
{
//空树也是完全二叉树
if (!root)
return true;
//首先根节点入队列
queue.push(root);
while(!queue.empty())
{
Node* node = queue.pop();
//处理左节点
if (!ProcessChild(node->left))
return false;
//处理右节点
if (!ProcessChild(node->right))
return false;
}
//广度优先遍历完毕,此乃完全二叉树
return true;
}
[方法二]
根据完全二叉树的定义,左边的深度>=右边的深度。从根节点开始,分别沿着最左最右分支下去,找到最左和最右的深度。如果左边比右边深1,再分别检查以左儿子和右儿子为根的两根树。有点递归的感觉了。
[To be continued...]
以3层二叉树为例,以下情况为完全二叉树:
[方法一]
这个问题的描述已经提示了解法,采用广度优先遍历,从根节点开始,入队列,如果队列不为空,循环。遇到第一个没有左儿子或者右儿子的节点,设置标志位,如果之后再遇到有左/右儿子的节点,那么这不是一颗完全二叉树。
这个方法需要遍历整棵树,复杂度为O(N),N为节点的总数。
[cpp]
view plaincopy
//二叉树结点定义
typedef struct Node
{
int data;
struct Node* left;
struct Node* right;
}Node;
//实现广度遍历需要队列
Queue<Node*> queue;
//第n层最右节点标志
bool leftMost = false;
bool ProcessChild(Node* child)
{
if (child)
{
if (!leftMost)
{
queue.push(child);
}
else
{
return false;
}
}
else
{
leftMost = true;
}
return true;
}
bool IsCompleteBinaryTree(Node* root)
{
//空树也是完全二叉树
if (!root)
return true;
//首先根节点入队列
queue.push(root);
while(!queue.empty())
{
Node* node = queue.pop();
//处理左节点
if (!ProcessChild(node->left))
return false;
//处理右节点
if (!ProcessChild(node->right))
return false;
}
//广度优先遍历完毕,此乃完全二叉树
return true;
}
[方法二]
根据完全二叉树的定义,左边的深度>=右边的深度。从根节点开始,分别沿着最左最右分支下去,找到最左和最右的深度。如果左边比右边深1,再分别检查以左儿子和右儿子为根的两根树。有点递归的感觉了。
[To be continued...]
相关文章推荐
- POJ2240 Arbitrage(Floyd判负环)
- aix 下 实现goldengate 随os启动而自己主动启动的脚本
- vsftp搭建
- BZOJ 2631 TREE
- JavaScript 操作 Cookie
- squid搭建
- Bitmap二次采样以及压缩另一种方式
- Linux网络相关命令小结
- 路是自己选的,这是一种生的宿命
- NSDate和NSDateFormatter
- iOS 学习(Whereami)
- 用闭包实现含有定时器的tab栏的切换与函数封装
- 学习远控界面设计一: 程序界面大小
- samba搭建
- 重装系统后必装软件
- java中的this关键字
- 每天一个Linux之locate命令
- map中使用自定义类指针作为key
- WIN32服务程序(二):卸载服务
- dns搭建