您现在的位置是:首页 >技术交流 >二叉查找树(C++刷题笔记)网站首页技术交流
二叉查找树(C++刷题笔记)
简介二叉查找树(C++刷题笔记)
二叉查找树(C++刷题笔记)
二叉查找树
-
若左子树不空,左子树所有节点的值均小于或等于它根节点的值;
-
若右子树不空,右子树所有节点的值均大于或等于它根节点的值;
-
左右子树也是二叉查找树
-
等于的情况只能出现在左子树或右子树中的某一侧
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x):
val(x),left(NULL),right(NULL){}
};
插入节点
将某个节点a插入以b为根的BST中:
-
a.val<b.val :
如果b有左子树,则递归的将该节点插入至左子树为根的BST中
否则,将b.left赋值为该节点地址
-
a.val>=b.val:
如果b有右子树,递归将该节点插入右子树为根的BST中
否则,将b.right赋值为该节点地址
void BST_insert(TreeNode *root, TreeNode *node) {
if (node->val < root->val) {
if (root->left != NULL) {
BST_insert(root->left, node);
} else {
root->left = node;
}
} else {
if (root->right) {
BST_insert(root->right, node);
} else {
root->right = node;
}
}
}
测试
void preorder(TreeNode *node,int layer){
if(!node){
return;
}
for (int i=0;i<layer;i++){
cout<<">";
}
cout<<node->val;
preorder(node->left,layer+1);
cout<<"
";
preorder(node->right,layer+1);
}
int main() {
TreeNode root(8);
vector<TreeNode *>vec;
int ls[]={3,1,6,4,7,10,14,13};
for (int i = 0; i <8 ; ++i) {
vec.push_back(new TreeNode(ls[i]));
}
for (int i = 0; i <vec.size(); ++i) {
BST_insert(&root,vec[i]);
}
preorder(&root,0);
return 0;
}
8>3>>1
>>6>>>4
>>>7
>10
>>14>>>13
查找数值
查找数值val是否在二叉树中出现
-
val==当前节点node节点值:返回真
-
val<当前节点node节点值:
如果node有左子树,继续在左子树中查找该值;否则返回假
-
val>当前节点node节点值:
如果node有右子树,继续在右子树中查找该值;否则返回假
bool BST_search(TreeNode *node, int val) {
if (node->val == val) {
return true;
}
if (val < node->val) {
if (node->left) {
return BST_search(node->left, val);
} else {
return false;
}
} else {
if (node->right) {
return BST_search(node->right, val);
} else {
return false;
}
}
}
449. 序列化和反序列化二叉搜索树
编码:
- 将二叉树先序遍历,遍历将整型数据转为字符串并拼接,链接时使用符号分割
解码:
- 将字符串按照编码时的分隔符,将各个数字拆分出来,将第一个数字变成构建二叉树的根节点,后面数字根据解析顺序插入根节点中去,返回根节点
void int2str(int val,string &str){
string tmp;
while (val){
tmp+=val%10+'0';
val=val/10;
}
for (int i = tmp.length()-1; i >=0 ; --i) {
str+=tmp[i];
str+='#';
}
}
void BST_preorder(TreeNode *node,string &data){
if(!node){
return;
}
string str;
int2str(node->val,str);
data+=str;
BST_preorder(node->left,data);
BST_preorder(node->right,data);
}
题目代码
class Codec {
public:
void int2str(int val, string &str) {
string tmp;
while (val) {
tmp += val % 10 + '0';
val = val / 10;
}
for (int i = tmp.length() - 1; i >= 0; --i) {
str += tmp[i];
}
str += '#';
}
void BST_insert(TreeNode *root, TreeNode *node) {
if (node->val < root->val) {
if (root->left != NULL) {
BST_insert(root->left, node);
} else {
root->left = node;
}
} else {
if (root->right) {
BST_insert(root->right, node);
} else {
root->right = node;
}
}
}
// Encodes a tree to a single string.
string serialize(TreeNode *root) {
string data;
BST_preorder(root, data);
return data;
}
// Decodes your encoded data to tree.
TreeNode *deserialize(string data) {
if (data.length() == 0) {
return NULL;
}
vector<TreeNode *> vec;
int val = 0;
for (int i = 0; i < data.length(); ++i) {
if (data[i] == '#') {
vec.push_back(new TreeNode(val));
val = 0;
} else {
val = val * 10 + data[i] - '0';
}
}
for (int i = 1; i < vec.size(); ++i) {
BST_insert(vec[0], vec[i]);
}
return vec[0];
}
void BST_preorder(TreeNode *node, string &data) {
if (!node) {
return;
}
string str;
int2str(node->val, str);
data += str;
BST_preorder(node->left, data);
BST_preorder(node->right, data);
}
};
315. 计算右侧小于当前元素的个数
记录左子树数量的二叉树
struct node{
int val;
int cnt;
node *left;
node *right;
node(int x):val(x),left(NULL),right(NULL),cnt(0){}
};
-
按照数组逆置后的顺序插入二叉查找树, 插入时,计算已有多少个元素比当前插入元素小
-
设置lower=0,记录插入过程中,有多少个元素比插入节点值小
-
若待插入节点值小于等于当前node值,node.cnt++,递归将该节点插入到当前节点左子树;
-
若待插入节点大于当前node值,lower+=node.cnt++,递归将该节点插入右子树
void insert(node *nd, node *insert_nd, int &lower) {
if (insert_nd->val <= nd->val) {
nd->cnt++;
if (nd->left) {
insert(nd->left, insert_nd, lower);
} else {
nd->left = insert_nd;
}
} else {
lower += nd->cnt + 1;
if (nd->right) {
insert(nd->right, insert_nd, lower);
} else {
nd->right = insert_nd;
}
}
}
题目代码
class Solution {
public:
struct node {
int val;
int cnt;
node *left;
node *right;
node(int x) : val(x), left(NULL), right(NULL), cnt(0) {}
};
void insert(node *nd, node *insert_nd, int &lower) {
if (insert_nd->val <= nd->val) {
nd->cnt++;
if (nd->left) {
insert(nd->left, insert_nd, lower);
} else {
nd->left = insert_nd;
}
} else {
lower += nd->cnt + 1;
if (nd->right) {
insert(nd->right, insert_nd, lower);
} else {
nd->right = insert_nd;
}
}
}
vector<int> countSmaller(vector<int> &nums) {
vector<int> res;//结果数组
vector<node *> vec;//存储二叉树节点
vector<int> cnt;//从后先前插入,比当前节点值小的
for (int i = nums.size() - 1; i >= 0; --i) {
vec.push_back(new node(nums[i]));//从后先前插入节点
}
cnt.push_back(0);//第一节点比它小的为0
for (int i = 1; i < vec.size(); ++i) {
int lower = 0;
insert(vec[0], vec[i], lower);
cnt.push_back(lower);//把比它小的个数插入进去
}
for (int i = vec.size() - 1; i >= 0; --i) {
res.push_back(cnt[i]);
}
return res;
}
};
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。