PAT甲级 二叉查找树 相关题_C++题解
二叉查找树
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++题解的更多相关文章
- PAT甲级 Dijkstra 相关题_C++题解
Dijkstra PAT (Advanced Level) Practice Dijkstra 相关题 目录 <算法笔记>重点摘要 1003 Emergency (25) <算法笔记 ...
- PAT甲级 二叉树 相关题_C++题解
二叉树 PAT (Advanced Level) Practice 二叉树 相关题 目录 <算法笔记> 重点摘要 1020 Tree Traversals (25) 1086 Tree T ...
- PAT甲级 图 相关题_C++题解
图 PAT (Advanced Level) Practice 用到图的存储方式,但没有用到图的算法的题目 目录 1122 Hamiltonian Cycle (25) 1126 Eulerian P ...
- PAT甲级 树 相关题_C++题解
树 目录 <算法笔记>重点摘要 1004 Counting Leaves (30) 1053 Path of Equal Weight (30) 1079 Total Sales of S ...
- PAT甲级 堆 相关题_C++题解
堆 目录 <算法笔记>重点摘要 1147 Heaps (30) 1155 Heap Paths (30) <算法笔记> 9.7 堆 重点摘要 1. 定义 堆是完全二叉树,树中每 ...
- PAT甲级 散列题_C++题解
散列 PAT (Advanced Level) Practice 散列题 目录 <算法笔记> 重点摘要 1002 A+B for Polynomials (25) 1009 Product ...
- PAT甲级 字符串处理题_C++题解
字符串处理题 目录 <算法笔记> 重点摘要 1001 A+B Format (20) 1005 Spell It Right (20) 1108 Finding Average (20) ...
- PAT甲级 并查集 相关题_C++题解
并查集 PAT (Advanced Level) Practice 并查集 相关题 <算法笔记> 重点摘要 1034 Head of a Gang (30) 1107 Social Clu ...
- PAT甲级 图的遍历 相关题_C++题解
图的遍历 PAT (Advanced Level) Practice 图的遍历 相关题 目录 <算法笔记>重点摘要 1021 Deepest Root (25) 1076 Forwards ...
随机推荐
- kvm 学习(二)镜像
Linux下 如何通过命令行使用现有的镜像创建.启动kvm虚拟机 这里假定已经创建好了相应的镜像: eg:我这里制作的镜像名称为zu1-centos7.img # ls zu1-centos7.img ...
- 将页面中所有的checkbox设成单选得
$(function () { var allBox = $(":checkbox"); allBox.click(function () { allBox.removeAttr( ...
- Lucene4.2源码解析之fdt和fdx文件的读写(续)——fdx文件存储一个个的Block,每个Block管理着一批Chunk,通过docID读取到document需要完成Segment、Block、Chunk、document四级查询,引入了LZ4算法对fdt的chunk docs进行了实时压缩/解压
2 索引读取阶段 当希望通过一个DocId得到Doc的全部内容,那么就需要对fdx/fdt文件进行读操作了.具体的代码在CompressingStoredFieldsReader类里面.与 ...
- [ambari环境搭建](未完待续)
[安装] https://blog.csdn.net/Happy_Sunshine_Boy/article/details/86595945#commentBox https://www.jiansh ...
- 关于Vue.use()详解
问题 相信很多人在用Vue使用别人的组件时,会用到 Vue.use() .例如:Vue.use(VueRouter).Vue.use(MintUI).但是用 axios时,就不需要用 Vue.use( ...
- PyTorch Tutorials 4 训练一个分类器
%matplotlib inline 训练一个分类器 上一讲中已经看到如何去定义一个神经网络,计算损失值和更新网络的权重. 你现在可能在想下一步. 关于数据? 一般情况下处理图像.文本.音频和视频数据 ...
- python 简化数据结构的初始化二 支持关键字参数
1.例子 学自cookbook3
- LC 990. Satisfiability of Equality Equations
Given an array equations of strings that represent relationships between variables, each string equa ...
- throws和throw的使用
throws 用在方法定义上 后面跟一个或者多个异常名称 如果是多个异常名称,之间使用","隔开 , 表达的意思是给该方法添加一个或者多个异常声明; 告诉调用者该方法可能会出现问题 ...
- ISO/IEC 9899:2011 条款6.4.5——字符串字面量
6.4.5 字符串字面量 语法 1.string-literal: encoding-prefixopt " s-char-sequenceopt " encoding- ...