阿里笔试附加题第一小题
2015-09-06 22:38
190 查看
给出一组整数对 { (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)},输出是下列二叉树:
提示:1) 构造出的二叉树的形态是存在且唯一的。 2) 想办法确定树根。
问题二:已知满足上述条件的二叉树,设计算法实现插入一个整对 (a, b),使新的二叉树仍满足上述条件。该算法比较复杂,候选人只需描述思路。
问题一思路,先建立大根堆,再构建BST
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)},输出是下列二叉树:
提示:1) 构造出的二叉树的形态是存在且唯一的。 2) 想办法确定树根。
问题二:已知满足上述条件的二叉树,设计算法实现插入一个整对 (a, b),使新的二叉树仍满足上述条件。该算法比较复杂,候选人只需描述思路。
问题一思路,先建立大根堆,再构建BST
struct pair_t { int a, b; }; struct node_t { int a, b; node_t *left, *right; }; void BSTInsert(node_t ** p, struct pair_t pair) { if(*p == NULL) { *p = (node_t *)malloc(sizeof(struct node_t)); (*p)->a = pair.a; (*p)->b = pair.b; (*p)->left = NULL; (*p)->right = NULL; } else if((*p)->a > pair.a) { BSTInsert(&(*p)->left, pair); } else { BSTInsert(&(*p)->right, pair); } } void CreateBST(node_t ** node, struct pair_t pair[], int num) { *node = NULL; for(int i = 0; i < num; i++) { BSTInsert(node, pair[i]); } } void InOrder(node_t *node) { if(node) { InOrder(node->left); printf("(%d %d) ", node->a, node->b); InOrder(node->right); } } void Print(struct pair_t pair[], int num) { for(int i = 0; i < num; i++) { printf("(%d %d) ", pair[i].a, pair[i].b); } printf("\n"); } void MaxHeapFixDown(struct pair_t pair[], int i, int n)//n 是节点个数 { int j = i * 2 + 1; int temp = pair[i].b; int temp2 = pair[i].a; while(j < n) { if(j + 1 < n && pair[j].b < pair[j+1].b) j++; if(temp > pair[j].b) { break; } else { pair[i].a = pair[j].a; pair[i].b = pair[j].b; i = j; j = 2 * i + 1; } } pair[i].b = temp; pair[i].a = temp2; } void CreateMaxHeap(struct pair_t pair[], int num) { for(int i = num / 2 - 1; i >= 0; --i) { MaxHeapFixDown(pair, i, num); } } int _tmain(int argc, _TCHAR* argv[]) { struct pair_t pair[] = {{5,8}, {2,10}, {4,3}, {1,5}, {0,2}, {9,1}}; CreateMaxHeap(pair, 6);//构建大根堆 Print(pair, 6); node_t *node; CreateBST(&node, pair, 6); printf("中序遍历结果如下:\n"); InOrder(node); getchar(); return 0; }
相关文章推荐
- TCP的发送系列 — tcp_sendmsg()的实现(二)
- c++ 联合体
- JsonModel的使用
- centos7 install 安装mysql
- TCP/IP、Http、Socket的区别
- 命令行连接mysql服务器时 报Can't connect to local MySQL server through socket 'xxx.sock'错误
- yii2之登录表单
- python学习笔记---类的方法与普通方法的区别
- HTML+CSS入门
- python scrapy爬虫
- iOS 刚刚,几分钟前,几小时前,几天前,几月前,几年前
- iOS-偏好设置保存数据
- Kernel compiling for Pi 2
- 学习日志---线索二叉树和翻转二叉树
- 决策树
- 数据挖掘概述
- ajax加载报abort错误解决方法
- linux查看某个端口号的所有连接状态
- c 语言 将整数 转换为 2 ,8,16 进制数
- 如何查看ubuntu的内核版本和发行版本号?