第一题:
给出一组整数对 { (a[0], b[0]), (a[1], b[1]) ... (a[n-1], b[n-1]) },所有 a 值 和 b 值分别不重复(任意 i != j 满足 a[i] != a[j] 且 b[i] != b[j])。构造一棵 n 结点的二叉树,将这 n 个整数对分配到各个结点上。根和所有子树满足以下条件:
1) 所有结点的 a 值满足二叉查找树的顺序,即 left->a < root->a && root->a < right->a;
2) 所有结点的 b 值满足最大堆的顺序,即 root->b > left->b && root->b > right->b。
问题一:实现 build 函数,输入 n 个整数对,返回一棵构造好的二叉树。
struct pair_t {
int a, b;
};
struct node_t {
int a, b;
node_t *left, *right;
};
node_t* build(pair_t* pair, int n);
例如,输入是 {(5, 8), (2, 10), (4, 3), (1, 5), (0, 2), (9, 1)},输出是下列二叉树:
![](https://img.alicdn.com/tps/i4/TB10JDmIVXXXXXeapXXIvPASXXX-410-205.jpg)
提示:1) 构造出的二叉树的形态是存在且唯一的。 2) 想办法确定树根。
问题二:已知满足上述条件的二叉树,设计算法实现插入一个整对 (a, b),使新的二叉树仍满足上述条件。该算法比较复杂,候选人只需描述思路。
第二题:
假设目前有3个程序A, B和C,需要相互传输数据,我们需要给做一个中转程序P。
A 读写的数据是经过某压缩格式azip压缩过的。
B 读写的数据需要base64编码。
C 读写数据需要压缩格式bzip压缩后base64编码。
现在假设已有工具函数 :
std::string azip(const std::string& input);
std::string aunzip(const std::string& input);
std::string base64encode(const std::string& input);
std::string base64decode(const std::string& input);
bool bzip(const std::string& input, std::string* output);
bool bunzip(const std::string& input, std::string* output);
请给中转程序 P 设计格式转换的工具类。注意设计的通用性,比如:可能有新的角色加入,要求给做加密解密等。
第三题:
假设我们已有一个函数,
int recv(char* buf, int len);
这个函数要求你准备一个 buffer,并告诉这个函数这个 buffer 有多长(len),这个函数就会在 buffer 里填上一些字符,并返回字符的个数(返回值永远 > 0 )。
请写出这样一个函数,
char* read_line() {
// ??? 你要写的代码
}
这个函数不需要任何参数,内部是靠调用 recv() 来拿到一些字符,然后要搜索回车字符 \n,找到后返回之前的字符,比如,
如果 recv() 拿到 "123\n45\n678",那第一次调用 read_line(),需要返回 "123"
但是请注意,第二次调用时,要返回 "45" (第二行字符窜)
第三次调用时,"678" 还没用掉,可是因为 678 之后没有 \n,所以你要继续调用 recv(),拿到更多字符,
假如 recv() 返回 "abc",你有了 "678abc",可是因为 abc 之后没有 \n,所以你要继续调用 recv(),拿到更多字符
假如 recv() 返回 "de\n" ,你有了 "678abcde\n", 因为看到了 \n ,所以你可以直接返回 "678abcde" 了。
图片版:
第一题:
第二题:
第三题: