二叉排序树的合并
题目描述
设计一个算法,将两棵二叉排序树合并成一颗二叉排序树。二叉排序树采用二叉链表存储。
输入格式
输入的第一行包含两个整数,分别表示两棵二叉排序树的节点数量 n
和 m
。
接下来的一行包含 n
个整数,表示第一棵二叉排序树的节点值。
再接下来的一行包含 m
个整数,表示第二棵二叉排序树的节点值。
输出格式
输出一行,包含 n+m
个整数,表示合并后的二叉排序树的中序遍历结果。
样例 #1
样例输入 #1
5 3
10 5 15 3 7
12 6 18
样例输出 #1
3 5 6 7 10 12 15 18
思路
利用二叉搜索树的一个重要性质:中序遍历二叉搜索树可以得到一个升序序列。因此,可以通过中序遍历 T1
和 T2
,并将遍历到的每个节点插入到 dst
中,从而得到一个包含 T1
和 T2
所有节点的新二叉搜索树。
inorderInsert
函数的实现递归中序遍历,先遍历左子树,然后访问当前节点,最后遍历右子树。
首先调用 inorderInsert
函数对 T1
进行中序遍历,并将遍历到的每个节点插入到 dst
中。然后,对 T2
做同样的操作。
算法分析
在时间复杂度上,需要遍历 T1
和 T2
的所有节点,所以时间复杂度是
O
(
n
+
m
)
O(n+m)
O(n+m),其中
n
n
n 和
m
m
m 分别是 T1
和 T2
的节点数量。在空间复杂度上,由于使用了递归,所以空间复杂度是
O
(
h
)
O(h)
O(h),其中
h
h
h 是 T1
和 T2
中较高的那棵树的高度。
AC代码
#include <algorithm>
#include <iostream>
#define AUTHOR "HEX9CF"
using namespace std;
using Status = int;
using ElemType = int;
const int N = 1e6 + 7;
const int TRUE = 1;
const int FALSE = 0;
const int OK = 1;
const int ERROR = 0;
const int INFEASIBLE = -1;
// const int OVERFLOW = -2;
int n, m;
ElemType a[N], b[N];
struct TreeNode {
ElemType data;
TreeNode *left, *right;
};
using BiTree = TreeNode *;
Status insertBST(BiTree &T, ElemType e) {
if (!T) {
T = (TreeNode *)malloc(sizeof(TreeNode));
if (!T) {
return ERROR;
}
T->data = e;
T->left = T->right = nullptr;
return OK;
} else if (e < T->data) {
return insertBST(T->left, e);
} else if (e > T->data) {
return insertBST(T->right, e);
}
return OK;
}
void inorderPrint(BiTree &T) {
if (T) {
inorderPrint(T->left);
cout << T->data << " ";
inorderPrint(T->right);
}
}
void inorderInsert(BiTree &T, BiTree &dst) {
if (T) {
inorderInsert(T->left, dst);
insertBST(dst, T->data);
inorderInsert(T->right, dst);
}
}
void mergeTrees(BiTree T1, BiTree T2, BiTree &dst) {
inorderInsert(T1, dst);
inorderInsert(T2, dst);
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i < m; i++) {
cin >> b[i];
}
BiTree bst1, bst2, bst3;
bst1 = bst2 = bst3 = nullptr;
for (int i = 0; i < n; i++) {
insertBST(bst1, a[i]);
}
for (int i = 0; i < m; i++) {
insertBST(bst2, b[i]);
}
// inorderPrint(bst1);
// cout << endl;
// inorderPrint(bst2);
// cout << endl;
mergeTrees(bst1, bst2, bst3);
inorderPrint(bst3);
// cout << endl;
return 0;
}