合并二叉树

Posted HelloCoding08

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合并二叉树相关的知识,希望对你有一定的参考价值。

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点

便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NUL L 的节点将直接作为新二叉树的节点。

例如


#include <stdio.h>#include <stdlib.h>
#define MAX_SIZE 10
typedef struct node Node;typedef struct node* Tree;typedef struct node* ElemType;typedef struct queue Queue;//队列和上一篇一样,只是把ElemType 换成 node*struct queue { ElemType elem[MAX_SIZE]; int front; int rear;};struct node { int elem; Node* lchild; Node* rchild;};
Queue* initial_queue () { Queue* queue = (Queue*)malloc(sizeof(Queue)); queue->front = 0; queue->rear = 0; return queue;}
int is_empty (Queue* queue){ return queue->rear == queue->front ? 1 : 0;}int is_full (Queue* queue){ return (queue->rear + 1) % MAX_SIZE == queue->front ? 1 : 0;}int queue_size(Queue* queue){ if (queue->rear > queue->front){ return queue->rear - queue->front; }else{ return queue->rear - queue->front + MAX_SIZE; }}
int push_elem (Queue* queue, ElemType elem){ if (is_full(queue)){ return 0; } queue->elem[queue->rear] = elem; queue->rear = (queue->rear + 1) % MAX_SIZE; return 1;}
int pop_elem (Queue* queue, ElemType* elem){ if (is_empty(queue)){ return 0; } *elem = queue->elem[queue->front]; queue->front = (queue->front + 1) % MAX_SIZE; return 1;}
int peek_elem (Queue* queue, ElemType* elem){ if (is_empty(queue)){ return 0; } *elem = queue->elem[queue->front]; return 1;}
int clear_queue (Queue* queue){ queue->front = 0; queue->rear = 0; return 1;}
int destroy (Queue** queue){ free(*queue); *queue = NULL; return 1;}//创建树的方式,递归创建。我好像也写了一篇Tree create_tree (FILE* fp){ Tree tree; int elem; fscanf(fp, "%d", &elem); if(elem == 0){ return NULL; }else{ tree = (Node*)malloc(sizeof(Node)); tree->elem = elem; tree->lchild = create_tree(fp); tree->rchild = create_tree(fp); } return tree;}//第一种方法(DFS)//合并两棵二叉树,会有下面3种情况//树的两个节点都是空,那就不需要合并了//树的两个节点一个为空一个不为空,那么合并的结果肯定是不为空的那个节点//树的两个节点都不为空,那么合并的节点值就是这个两个节点的和Tree merge_tree (Tree tree1, Tree tree2){    //如果两个节点都为空,直接返回空    if (tree1 == NULL && tree2 == NULL){ return NULL; } //如果tree1节点为空,就返回t2节点 if (tree1 == NULL){ return tree2; }    //如果tree2节点为空,就返回t1节点 if (tree2 == NULL){ return tree1; } //合并成一个新的节点 Tree tree = (Tree)malloc(sizeof(Node)); tree->elem = tree1->elem + tree2->elem;    //递归合并t1和t2的子节点 tree->lchild = merge_tree(tree1->lchild, tree2->lchild); tree->rchild = merge_tree(tree1->rchild, tree2->rchild); return tree;}//第二种方法(BFS)//把第2棵树合并到第1棵树上//如果树1的左子节点为空,直接把第2棵树的左子节点赋给第1棵树的左子节点即可//如果树1的左子节点不为空,树2的左子节点为空,直接返回树1的左子节点即可//如果树1的左子节点和树2的左子节点都不为空,直接相加。Tree merge_tree(Tree tree1, Tree tree2){ //如果tree1节点为空,就返回t2节点 if (tree1 == NULL){ return tree2; } ////如果tree2节点为空,就返回t1节 if (tree2 == NULL){ return tree1; } //队列中两棵树的节点同时存在, //把这两棵树的节点同时入队 Queue* queue = initial_queue(); push_elem(queue, tree1); push_elem(queue, tree2); Node* node1; Node* node2; while(!is_empty(queue)){        //两棵树的节点同时出队 pop_elem(queue, &node1); pop_elem(queue, &node2); //把这两个节点的值相加,然后合并到第1棵树的节点上 node1->elem += node2->elem;        //如果node1左子节点为空,我们直接让node2的,左子结点成为node1的左子结点, if (node1->lchild == NULL){ node1->lchild = node2->lchild; }else{ if (node2->lchild != NULL){ //说明node1的左子节点不为空                //如果node2的左子节点为空就不需要合并了,                //只有node2的左子节点不为空的时候才需要合并 push_elem(queue, node1->lchild); push_elem(queue, node2->lchild); } }        //和上面的同理 if (node1->rchild == NULL){ node1->rchild = node2->rchild; }else{ if (node2->rchild != NULL){ push_elem(queue, node1->rchild); push_elem(queue, node2->rchild); } } } destroy(&queue); return tree1;}
void pre_order (Tree tree){ if(tree != NULL){ printf("%d\t", tree->elem); pre_order(tree->lchild); pre_order(tree->rchild); }}
int main () { char* path1 = "./demo01.txt"; char* path2 = "./demo02.txt"; FILE* fp1 = fopen(path1, "r"); FILE* fp2 = fopen(path2, "r"); if (fp1 == NULL || fp2 == NULL){ perror("fopen error"); return -1; } Tree tree1 = create_tree(fp1); Tree tree2 = create_tree(fp2); pre_order(tree1); printf("\n"); pre_order(tree2); printf("\n"); fclose(fp1); fclose(fp2); Tree tree = merge_tree(tree1, tree2); pre_order(tree); printf("\n"); return 0;}

合并二叉树

demo01.txt

demo02.txx


以上是关于合并二叉树的主要内容,如果未能解决你的问题,请参考以下文章

二叉树oj ---->合并二叉树

⭐算法入门⭐《深度优先搜索》简单02 —— LeetCode 617. 合并二叉树

二叉树--合并二叉树

二叉树20:合并两个二叉树

不确定为啥这个特定的测试用例不适用于合并二叉树

LeetCode617合并二叉树