1.二叉树求镜像
什么是二叉树的镜像?
如上,右边就是左边这棵树的镜像;
由上图可以看出,求一颗树的镜像就是将二叉树的左右子树交换即可;
这里用递归和非递归两种方法进行求解:
递归实现:
void TreeMirror(TreeNode* root){
if(root == NULL){
return;
}
//访问动作就是交换左右子树
Swap(&root->lchild,&root->rchild);
TreeMirror(root->lchild);
TreeMirror(root->rchild);
}
非递归实现:
void TreeMirrorByLoop(TreeNode* root){
if(root == NULL){
return;
}
SeqQueue q;
SeqQueueInit(&q);
SeqQueuePush(&q,root);
TreeNode* front = NULL;
while(SeqQueueFront(&q,&front)){
Swap(&front->lchild,&front->rchild);
SeqQueuePop(&q);
if(front->lchild != NULL){
SeqQueuePush(&q,front->lchild);
}
if(front->rchild != NULL){
SeqQueuePush(&q,front->rchild);
}
}
return;
}
2.判断一颗树是否是完全二叉树;
首先,有如下几种树均是完全二叉树:
由以上情况,我们可以对完全对完全二叉树有以下解释:
首先这里使用层序遍历的方法,进行遍历,遍历的过程分为两个阶段:
阶段一:任何一个结点同时具有左右子树(上图中情况1),一旦发现某个结点不是同时具备,又分为三种情况
a)当前结点只有右子树,一定不是完全二叉树;
b)如果当前结点只有左子树,进入第二阶段;
c)如果当前结点没有子树,也进入第二阶段;
阶段二:任何一个结点都必须没有子树.
当遍历结束之后,所有的条件都满足,说明这个树就是完全二叉树,否则,就不是.
代码实现如下:
int IsCompleteTree(TreeNode* root){
if(root == NULL){
return 0;
}
SeqQueue q;
SeqQueueInit(&q);
SeqQueuePush(&q,root);
//这个变量表示是否要进入第二阶段
int if_start_step_two_flag = 0;
TreeNode* cur = NULL;
while(SeqQueueFront(&q,&cur)){
SeqQueuePop(&q);
if(if_start_step_two_flag == 0){
//阶段一
if(cur->lchild != NULL && cur->rchild != NULL){
//同时具备左右子树
SeqQueuePush(&q,cur->lchild);
SeqQueuePush(&q,cur->rchild);
}else if(cur->rchild != NULL && cur->lchild == NULL){
//不是完全二叉树
return 0;
}else if(cur->rchild == NULL && cur->lchild != NULL){
//当前节点只有左子树没有右子树,进入第二阶段
if_start_step_two_flag = 1;
SeqQueuePush(&q,cur->lchild);
}else {
//没有左右子树
if_start_step_two_flag = 1;
}
}else {
//阶段二
if(cur->lchild == NULL && cur->rchild ==NULL){
;
}else{
return 0;
}
}//end阶段一和阶段二的判定
}//循环结束
//所有节点都判定完了,此时又没有return 0,此时一定是完全二叉树
return 1;
}
3.根据先序和中序遍历的结果重建这棵树;
首先,先序遍历的第一个结点肯定是根结点,然后拿这个结点在中序遍历中找相应的位置,它的左右两边的结点即是它的左右子树,依次这样取下一个先序遍历的结点,再去找中序遍历中相对应的位置,循环;
具体代码实现如下:
TreeNode* _TreeRebuild(TreeNodeType pre_order[],size_t pre_order_size,size_t* pre_order_inde
TreeNodeType in_order[],size_t in_order_left,size_t in_order_right){
if(in_order_left >= in_order_right){
//无效区间,当前子树中序遍历结果为空,此时说明这棵子树是空树
return NULL;
}
if(pre_order_index == NULL || *pre_order_index >= pre_order_size){
//pre_order_index == NULL非法输入
//*pre_order_index >= pre_order_size 遍历完了
return NULL;
}
//根据先序遍历结果取出当前值,基于这个值构建一个节点
//new_node 相当于当前子树的根结点
TreeNode* new_node = CreateTreeNode(pre_order[*pre_order_index]);
//查找一下当前节点在中序遍历中的位置
size_t cur_root_in_order_index = Find(in_order,in_order_left,in_order_right,new_node->data);
//assert(cur_root_in_order_index != (size_t)-1);
++(*pre_order_index);
//左子树区间[in_order_left,cur_root_in_order_index)
new_node->lchild = _TreeRebuild(pre_order,pre_order_size,pre_order_index,in_order,in_order_left,cur_root_in_order_index);
//右子树区间[cur_root_in_order_index+1,in_order_right)
new_node->rchild = _TreeRebuild(pre_order,pre_order_size,pre_order_index,in_order,cur_root_in_order_index+1,in_order_right);
return new_node;
}
TreeNode* TreeRebuild(TreeNodeType pre_order[],TreeNodeType in_order[],size_t size){
size_t pre_order_index = 0;
size_t in_order_right = size;
//[in_order_left,in_order_right)
return _TreeRebuild(pre_order,size,&pre_order_index,in_order,in_order_left,in_order_right);
}
size_t Find(TreeNodeType arry[],size_t left,size_t right,TreeNodeType to_find){
size_t i = left;
for(;i<right;i++){
if(arry[i] == to_find){
return i;
}
}
return (size_t)-1;
}