二叉查找树

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. kvm 学习(二)镜像

    Linux下 如何通过命令行使用现有的镜像创建.启动kvm虚拟机 这里假定已经创建好了相应的镜像: eg:我这里制作的镜像名称为zu1-centos7.img # ls zu1-centos7.img ...

  2. 将页面中所有的checkbox设成单选得

    $(function () { var allBox = $(":checkbox"); allBox.click(function () { allBox.removeAttr( ...

  3. Lucene4.2源码解析之fdt和fdx文件的读写(续)——fdx文件存储一个个的Block,每个Block管理着一批Chunk,通过docID读取到document需要完成Segment、Block、Chunk、document四级查询,引入了LZ4算法对fdt的chunk docs进行了实时压缩/解压

    2       索引读取阶段 当希望通过一个DocId得到Doc的全部内容,那么就需要对fdx/fdt文件进行读操作了.具体的代码在CompressingStoredFieldsReader类里面.与 ...

  4. [ambari环境搭建](未完待续)

    [安装] https://blog.csdn.net/Happy_Sunshine_Boy/article/details/86595945#commentBox https://www.jiansh ...

  5. 关于Vue.use()详解

    问题 相信很多人在用Vue使用别人的组件时,会用到 Vue.use() .例如:Vue.use(VueRouter).Vue.use(MintUI).但是用 axios时,就不需要用 Vue.use( ...

  6. PyTorch Tutorials 4 训练一个分类器

    %matplotlib inline 训练一个分类器 上一讲中已经看到如何去定义一个神经网络,计算损失值和更新网络的权重. 你现在可能在想下一步. 关于数据? 一般情况下处理图像.文本.音频和视频数据 ...

  7. python 简化数据结构的初始化二 支持关键字参数

    1.例子 学自cookbook3

  8. LC 990. Satisfiability of Equality Equations

    Given an array equations of strings that represent relationships between variables, each string equa ...

  9. throws和throw的使用

    throws 用在方法定义上 后面跟一个或者多个异常名称 如果是多个异常名称,之间使用","隔开 , 表达的意思是给该方法添加一个或者多个异常声明; 告诉调用者该方法可能会出现问题 ...

  10. ISO/IEC 9899:2011 条款6.4.5——字符串字面量

    6.4.5 字符串字面量 语法 1.string-literal: encoding-prefixopt    "  s-char-sequenceopt  " encoding- ...