二叉查找树

PAT (Advanced Level) Practice 二叉查找树 相关题

目录

  • 《算法笔记》 重点摘要
  • 1099 Build A Binary Search Tree (30)
  • 1115 Counting Nodes in a BST (30)
  • 1143 Lowest Common Ancestor (30)

《算法笔记》 9.4 二叉查找树 重点摘要

二叉查找树静态实现 ⭐

(1) 定义
struct Node{
typename data;
int level;
int lchild;
int rchild;
} node[MAXN];
(2) 新建结点
int index = 0;
int newNode (int value){
// node[index] = {value,-1,-1};
node[index].data = value;
node->lchild = node->rchild = -1;
return index++;
}
(3) 插入
void insert (int &root, int value){
if (root == -1){
root = newNode(value);
return;
}
if (root->data == value) return;
else if (root->data > value) insert(root->lchild, value);
else insert(root->rchild, value);
}
(4) 创建
int create (int value[], int n){
int root = -1;
for (int i = 0; i < n; i++) insert(root, value[i]);
return root;
}
(5) 查找&修改
void search (int root, int value, int newvalue){
if (root == -1) return;
if (root->data == value) root->data = newvalue;
else if (root->data > value) search(root->lchild, value, newvalue);
else search(root->rchild, value, newvalue);
}
(6) 删除
int findMax (int root){
while (root->rchild != -1) root = root->rchild;
return root;
}
int findMin (int root){
while (root->lchild != -1) root = root->lchild;
return root;
}
void deleteNode (int &root, int value){
if (root == -1) return;
if (root->data == value){
if (root->lchild == -1 && root->rchild == -1)
root = -1;
else if (root->lchild != -1){
int pre = findMax(root->lchild);
root->data = pre->data;
deleteNode(root->lchild, pre->data);
}
else{
int next = findMin(root->rchild);
root->data = next->data;
deleteNode(root->rchild, next->data);
}
}
else if (root->data > value) deleteNode(root->lchild, value);
else deleteNode(root->rchild, value);
}

1099 Build A Binary Search Tree (30)

题目思路

  • 主要需要树的结构,其中数据需要后面填,用 vector<pair<int,int>> 储存结点对应左右子结点即可
  • 将树结构接收进来后先中序遍历,得到树结点序号对应的中序序列
  • 再将数值接收进来,升序排列即为中序遍历
  • 以上可将结点序号和数值对应起来,为便于查找,开一个 match 容器,将数值填到结点序号对应位置
  • 对树作层序遍历,从队列中弹出结点时将对应的数值压入容器,最后按要求输出
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
vector<pair<int,int>> tree;
vector<int> in, level, data, match;
void inorder(int root){
if (root == -1) return;
inorder(tree[root].first);
in.push_back(root);
inorder(tree[root].second);
}
void levelorder(int root){
queue<int> q;
q.push(root);
while (!q.empty()){
int now = q.front();
level.push_back(match[now]);
q.pop();
if (tree[now].first != -1) q.push(tree[now].first);
if (tree[now].second != -1) q.push(tree[now].second);
}
}
int main()
{
int n;
scanf("%d", &n);
tree.resize(n);
for (int i = 0; i < n; i++)
scanf("%d%d", &tree[i].first, &tree[i].second);
data.resize(n);
for (int i = 0; i < n; i++)
scanf("%d", &data[i]);
sort(data.begin(), data.end());
inorder(0);
match.resize(n);
for (int i = 0; i < n; i++) match[in[i]] = data[i];
levelorder(0);
for (int i = 0; i < n; i++) printf("%d%c", level[i], i+1 == n ? '\n' : ' ');
return 0;
}

1115 Counting Nodes in a BST (30)

  • 注意:当树退化成一条链时,若根从1开始,则树深度有1000,levelnum 数组大小开为 1000 会越界=》根节点层数从 0 开始
#include<iostream>
using namespace std;
struct Node{
int data, lchild, rchild;
} node[1000];
int index = 0, depth = -1, levelnum[1000] = {0};
void insert(int &root, int value){
if (root == -1){
node[index] = {value, -1, -1};
root = index++;
}
else if (node[root].data >= value) insert(node[root].lchild, value);
else insert(node[root].rchild, value);
}
void DFS(int root, int level){
levelnum[level]++;
if (level > depth) depth = level;
if (node[root].lchild != -1) DFS(node[root].lchild, level+1);
if (node[root].rchild != -1) DFS(node[root].rchild, level+1);
}
int main()
{
int n, data, root = -1;
scanf("%d", &n);
for (int i = 0; i < n; i++){
scanf("%d", &data);
insert(root, data);
}
DFS(0,0);
printf("%d + %d = %d\n", levelnum[depth], levelnum[depth-1], levelnum[depth]+levelnum[depth-1]);
return 0;
}

1143 Lowest Common Ancestor (30)

题目思路

  • LCA 的性质:大于一个子节点,小于另一个子节点
  • 题目给出先序遍历
  • 依次判断是否符合 LCA 性质
  • 由于可能一个点是另一个点的祖先,应当允许 == 情况
  • ?为什么按先序遍历能得到呢orz
#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
int main()
{
int m, n, u, v, root;
scanf("%d%d", &m, &n);
vector<int> pre(n);
unordered_map<int,bool> keys;
for (int i = 0; i < n; i++){
scanf("%d", &pre[i]);
keys[pre[i]] = true;
}
for (int i = 0; i < m; i++){
scanf("%d%d", &u, &v);
if (!keys[u] && !keys[v]) printf("ERROR: %d and %d are not found.\n", u, v);
else if (!keys[u]) printf("ERROR: %d is not found.\n", u);
else if (!keys[v]) printf("ERROR: %d is not found.\n", v);
else{
for (root = 0; root < n; root++)
if ((pre[root] >= u && pre[root] <= v) || (pre[root] <= u && pre[root] >= v)) break;
if (pre[root] == u || pre[root] == v) printf("%d is an ancestor of %d.\n", pre[root]==u?u:v, pre[root]==u?v:u);
else printf("LCA of %d and %d is %d.\n", u, v, pre[root]);
}
}
return 0;
}

附:

二叉查找树链式实现

(1) 定义
struct Node{
typename data;
int level
Node* lchild;
Node* rchild;
}
(2) 新建结点
Node* newNode (int value){
Node* node = new Node;
node->data = value;
node->lchild = node->rchild = NULL;
return node;
}
(3) 插入
void insert (Node* &root, int value){
if (root == NULL){
root = newNode(value);
return;
}
if (root->data == value) return;
else if (root->data > value) insert(root->lchild, value);
else insert(root->rchild, value);
}
(4) 创建
Node* create (int value[], int n){
node* root = NULL;
for (int i = 0; i < n; i++) insert(root, value[i]);
return root;
}
(5) 查找&修改
void search (Node* root, int value, int newvalue){
if (root == NULL) return;
if (root->data == value) root->data = newvalue;
else if (root->data > value) search(root->lchild, value, newvalue);
else search(root->rchild, value, newvalue);
}
(6) 删除
Node* findMax (Node* root){
while (root->rchild != NULL) root = root->rchild;
return root;
}
Node* findMin (Node* root){
while (root->lchild != NULL) root = root->lchild;
return root;
}
void deleteNode (Node* root, int value){
if (root == NULL) return;
if (root->data == value){
if (root->lchild == NULL && root->rchild == NULL)
root = NULL;
else if (root->lchild != NULL){
Node* pre = findMax(root->lchild);
root->data = pre->data;
deleteNode(root->lchild, pre->data);
}
else{
Node* next = findMin(root->rchild);
root->data = next->data;
deleteNode(root->rchild, next->data);
}
}
else if (root->data > value) deleteNode(root->lchild, value);
else deleteNode(root->rchild, value);
}

PAT甲级 二叉查找树 相关题_C++题解的更多相关文章

  1. PAT甲级 Dijkstra 相关题_C++题解

    Dijkstra PAT (Advanced Level) Practice Dijkstra 相关题 目录 <算法笔记>重点摘要 1003 Emergency (25) <算法笔记 ...

  2. PAT甲级 二叉树 相关题_C++题解

    二叉树 PAT (Advanced Level) Practice 二叉树 相关题 目录 <算法笔记> 重点摘要 1020 Tree Traversals (25) 1086 Tree T ...

  3. PAT甲级 图 相关题_C++题解

    图 PAT (Advanced Level) Practice 用到图的存储方式,但没有用到图的算法的题目 目录 1122 Hamiltonian Cycle (25) 1126 Eulerian P ...

  4. PAT甲级 树 相关题_C++题解

    树 目录 <算法笔记>重点摘要 1004 Counting Leaves (30) 1053 Path of Equal Weight (30) 1079 Total Sales of S ...

  5. PAT甲级 堆 相关题_C++题解

    堆 目录 <算法笔记>重点摘要 1147 Heaps (30) 1155 Heap Paths (30) <算法笔记> 9.7 堆 重点摘要 1. 定义 堆是完全二叉树,树中每 ...

  6. PAT甲级 散列题_C++题解

    散列 PAT (Advanced Level) Practice 散列题 目录 <算法笔记> 重点摘要 1002 A+B for Polynomials (25) 1009 Product ...

  7. PAT甲级 字符串处理题_C++题解

    字符串处理题 目录 <算法笔记> 重点摘要 1001 A+B Format (20) 1005 Spell It Right (20) 1108 Finding Average (20) ...

  8. PAT甲级 并查集 相关题_C++题解

    并查集 PAT (Advanced Level) Practice 并查集 相关题 <算法笔记> 重点摘要 1034 Head of a Gang (30) 1107 Social Clu ...

  9. PAT甲级 图的遍历 相关题_C++题解

    图的遍历 PAT (Advanced Level) Practice 图的遍历 相关题 目录 <算法笔记>重点摘要 1021 Deepest Root (25) 1076 Forwards ...

随机推荐

  1. Java枚举抽象方法实战

    需求背景 需求已经确定了几个固定的常量值,并且每个常量值都有相同的行为,但是具体实现细节不同.建议使用枚举抽象方法,优点:结构清晰,便于扩展. 枚举类实现抽象方法 与常规抽象类一样,enum类允许我们 ...

  2. OpenFOAM动网格技术介绍【转载】

    转载自:http://blog.sina.com.cn/s/blog_e256415d0101nfhp.html Chalmers大学的Andreu Oliver González对OpenFOAM中 ...

  3. [RK3399] 虚拟按键栏显示不全或者方向不对

    CPU:RK3399 系统:Android 7.1 同样的系统代码,换了一个小分辨率的屏,虚拟按键栏就出现显示不全,而且方向不对 出现这种问题的原因是显示密度和屏不匹配,需要适当的降低显示密度即可 d ...

  4. javaWeb项目部署到阿里云服务器

    1.云服务器中配置了jdk+eclipse+tomcat 2.将项目导出War到安装的Tomcat的webapps文件夹中: 右击项目->Export->WarFile->Desti ...

  5. 本周JavaScript学习小结

    应组长杨老师号召,写个js阶段性学习小结. emmm这周学了Linux进程通讯,学正则表达式尝试完成第一次编程作业,中秋还去平潭露营(所以...js学得很少hhh). 现在还处于感性认识阶段,浏览了一 ...

  6. jeecg使用心得

    接触到jeecg框架是在去年,接触到了jeecg开源框架,此框架为企业级急速开发框架,不了解的可以百度下这类框架的,对于目前状态来说,此框架确实也满足了所需,此刻就开始接触jeecg框架,去年六七月份 ...

  7. new Handler()和new Handler(Looper.getMainLooper())的区别是什么?

    new Handler()和new Handler(Looper.getMainLooper())的区别是什么?     一.Handler的一些知识,new Handler()和new Handle ...

  8. sppNet论文学习

    Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition 深度神经网络中用于视觉识别的空间金字塔池化 ...

  9. ARM 之一 ELF文件、镜像(Image)文件、可执行文件、对象文件 详解

    [转]https://blog.csdn.net/ZCShouCSDN/article/details/100048461 ELF 文件规范   ELF(Executable and Linking ...

  10. Redis键通知机制

    Redis键通知机制 一.概念 自从redis2.8.0以后出了一个新特性,Keyspace Notifications 称为“键空间通知”. 这个特性大概是,凡是实现了Redis的Pub/Sub的客 ...