高阶数据结构:二叉搜索树
创始人
2024-02-10 17:07:43

本篇主要是在初级数据结构中介绍的二叉树的提升,了解二叉搜索树的特性。


文章目录

  • 一、二叉搜索树的概念
  • 二、二叉搜索树操作
    • 1、二叉搜索树的查找
    • 2、二叉搜索树的插入
    • 3、二叉搜索树的删除
  • 三、二叉搜索树的实现
  • 四、二叉搜索树的应用
  • 五、关于二叉树进阶面试题


一、二叉搜索树概念

概念:二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下特征:

一、它的左子树不为空,则左子树上所有的节点的值都小于根节点的值

二、它的右子树不为空,则右子树上所有的节点的值都大于根节点的值

三、它的左右子树也分别为二叉搜索树

如果所示:


二、二叉搜索树的操作

1.二叉搜索树的查找

bool Find(const K& key){Node* cur = _root;while (cur){if (cur->_key < key)cur = cur->_right;else if(cur->_key>key)cur = cur->_left;elsereturn true;}return false;}

2.二叉树的插入

	bool Insert(const K& key){//如果此时根结点不存在需要创建根结点if (_root == nullptr){_root = new Node(key);return true;}//插入新结点的时候需要将父类的节点进行连接Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_key < key){parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(key);if (parent->key < key)parent->_right = cur;elseparent->_left = cur;return true;}

 3.二叉树的删除

bool Erase(const K& key){Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_key < key){parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{//开始删除//左为空//右为空//左右都不为空//这里需要考虑根节点的情况if (cur->left == nullptr){if (cur->_left == nullptr){if (cur == _root){_root = cur->_right;}else{if (cur == parent->_left)parent->left = cur->_right;elseparent->_right = cur->right;}}delete cur;cur = nullptr;}else if (cur->_right == nullptr){if (_root == cur)_root = cur->_left;else{if (cur == parent->_left)parent->_left = cur->_left;elseparent->_right = cur->_left;}delete cur;cur = nullptr;}else{//找到右子树最小节点进行替换Node* minParent = cur;Node* min = cur->_right;while (min->_left){minParent = min;min = min->_left;}swap(cur->_key, min->_key);if (minParent->_left == min)minParent->_left = min->_right;elseminParent->_right = min->_right;delete min;}return true;}return false;}}

 三、二叉搜索树的实现

struct BSTreeNode
{BSTreeNode* _left;BSTreeNode* _right;K _key;BSTreeNode(const K& key):_left(nullptr), _right(nullptr), _key(key){}
};//class BinarySearchTree
template
class BSTree
{typedef BSTreeNode Node;
public:bool Insert(const K& key){if (_root == nullptr){_root = new Node(key);return true;}Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_key < key){parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(key);if (parent->_key < key){parent->_right = cur;}else{parent->_left = cur;}return true;}bool Find(const K& key){Node* cur = _root;while (cur){if (cur->_key < key){cur = cur->_right;}else if (cur->_key > key){cur = cur->_left;}else{return true;}}return false;}bool Erase(const K& key){Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_key < key){parent = cur;cur = cur->_right;}else if (cur->_key > key){parent = cur;cur = cur->_left;}else{// 开始删除// 1、左为空// 2、右为空// 3、左右都不为空if (cur->_left == nullptr){if (cur == _root){_root = cur->_right;}else{if (cur == parent->_left){parent->_left = cur->_right;}else{parent->_right = cur->_right;}}delete cur;cur = nullptr;}else if (cur->_right == nullptr){if (_root == cur){_root = cur->_left;}else{if (cur == parent->_left){parent->_left = cur->_left;}else{parent->_right = cur->_left;}}delete cur;cur = nullptr;}else{// 找到右子树最小节点进行替换Node* minParent = cur;Node* min = cur->_right;while (min->_left){minParent = min;min = min->_left;}swap(cur->_key, min->_key);if (minParent->_left == min)minParent->_left = min->_right;elseminParent->_right = min->_right;delete min;}return true;}}return false;}void InOrder(){_InOrder(_root);cout << endl;}/bool FindR(const K& key){return _FindR(_root, key);}bool InsertR(const K& key){return _InsertR(_root, key);}bool EraseR(const K& key){return _EraseR(_root, key);}~BSTree(){_Destory(_root);}/*BSTree(){}*/// C++的用法:强制编译器生成默认的构造BSTree() = default;BSTree(const BSTree& t){_root = _Copy(t._root);}// t2 = t1BSTree& operator=(BSTree t){swap(_root, t._root);return *this;}private:Node* _Copy(Node* root){if (root == nullptr){return nullptr;}Node* copyRoot = new Node(root->_key);copyRoot->_left = _Copy(root->_left);copyRoot->_right = _Copy(root->_right);return copyRoot;}void _Destory(Node*& root){if (root == nullptr){return;}_Destory(root->_left);_Destory(root->_right);delete root;root = nullptr;}bool _EraseR(Node*& root, const K& key){if (root == nullptr)return false;if (root->_key < key)return _EraseR(root->_right, key);else if (root->_key > key)return _EraseR(root->_left, key);else{Node* del = root;if (root->_left == nullptr){root = root->_right;}else if (root->_right == nullptr){root = root->_left;}else{// 找右树的最左节点替换删除Node* min = root->_right;while (min->_left){min = min->_left;}swap(root->_key, min->_key);//return EraseR(key);  错的return _EraseR(root->_right, key);}delete del;return true;}}bool _InsertR(Node*& root, const K& key){if (root == nullptr){root = new Node(key);return true;}if (root->_key < key)return _InsertR(root->_right, key);else if (root->_key > key)return _InsertR(root->_left, key);elsereturn false;}bool _FindR(Node* root, const K& key){if (root == nullptr)return false;if (root->_key < key)return _FindR(root->_right, key);else if (root->_key > key)return _FindR(root->_left, key);elsereturn true;}void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}
private:Node* _root = nullptr;
};

四、二叉搜索树的应用

1.K模型:K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到

的值

2.KV模型:每一个关键码key,都有与之对应的值Value,即的键值对

 五、关于二叉树进阶面试题


 

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:string tree2str(TreeNode* root) {if(root==nullptr)return string();string str;str+=to_string(root->val);//如果左子树不为空或者左右子树都不为空,左边需要加括号if(root->left||root->right){str+='(';str+=tree2str(root->left);str+=')';}//右边如果不为空,右边需要加括号if(root->right){str+='(';str+=tree2str(root->right);str+=')';}return str;}
};

 

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector> levelOrder(TreeNode* root) {//如果此时二叉树为空,则返回vector>的匿名对象if(root==nullptr)return vector>();//利用队列先进先出的特性进行判断queue q;//利用二维数组来保存当前没一层的节点vector> vv;int levelSize=1;//每一行的节点数q.push(root);//将此时的根节点如队while(!q.empty())//如果队列不为空就继续{vector v;for(int i=0;ival);if(front->left)q.push(front->left);if(front->right)q.push(front->right);}levelSize=q.size();//将此时队列中的个数求出来vv.push_back(v);}return vv;}
};

 

 

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector> levelOrderBottom(TreeNode* root) {//如果此时二叉树为空,则返回vector>的匿名对象if(root==nullptr)return vector>();//利用队列先进先出的特性进行判断queue q;//利用二维数组来保存当前没一层的节点vector> vv;int levelSize=1;//每一行的节点数q.push(root);//将此时的根节点如队while(!q.empty())//如果队列不为空就继续{vector v;for(int i=0;ival);if(front->left)q.push(front->left);if(front->right)q.push(front->right);}levelSize=q.size();//将此时队列中的个数求出来vv.push_back(v);}reverse(vv.begin(),vv.end());return vv;}
};

 

 

 

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {
public:bool Find(TreeNode*root,TreeNode*x,stack&path){if(root==nullptr) return false;path.push(root);if(root==x) return true;//如果没有找到从左子树开始找,如果没找到去右子树中找,如果都没有找到此时需要将所有的当前节点需要进行出栈的操作if(Find(root->left,x,path)) return true;if(Find(root->right,x,path)) return true;path.pop();return false;}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(root==nullptr)  return nullptr;//利用DFS来保存每一次搜索的路径stack pPath,qPath;Find(root,p,pPath);Find(root,q,qPath);//根据求两个链表公共节点的策略来求出二叉树中两个节点的最近的公共祖先的问题while(pPath.size()!=qPath.size()){if(pPath.size()>qPath.size()) pPath.pop();else qPath.pop();}while(pPath.top()!=qPath.top()){pPath.pop();qPath.pop();}return pPath.top();}
};

 

 

/*
struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x) :val(x), left(NULL), right(NULL) {}
};*/
class Solution {
public:void InOrderConvert(TreeNode*cur,TreeNode*&prev){if(cur==nullptr) return;//先找出左子树InOrderConvert(cur->left,prev);cur->left=prev;if(prev)prev->right=cur;prev=cur;InOrderConvert(cur->right,prev);}TreeNode* Convert(TreeNode* pRootOfTree) {TreeNode*prev=nullptr;InOrderConvert(pRootOfTree,prev);while(pRootOfTree&&pRootOfTree->left)pRootOfTree=pRootOfTree->left;return pRootOfTree;}
};

 

 

 

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public://利用前序来创建树,中序来分割区间TreeNode*buildTreeHelper(vector&preorder,vector&inorder,int& prei,int inbegin,int inend)//这里previ需要利用引用,因为下一次递归prei会发生改变{if(inbegin>inend) return nullptr;TreeNode*root=new TreeNode(preorder[prei++]);//将中序的区间进行划分int ini=inbegin;while(ini<=inend){if(inorder[ini]==root->val) break;else ++ini;}//利用分治法的思想继续分割左右区间root->left=buildTreeHelper(preorder,inorder,prei,inbegin,ini-1);root->right=buildTreeHelper(preorder,inorder,prei,ini+1,inend);return root;}TreeNode* buildTree(vector& preorder, vector& inorder) {int i=0;return buildTreeHelper(preorder,inorder,i,0,inorder.size()-1);}
};

 

 

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:TreeNode* buildTree(vector& inorder, vector& postorder) {}
};

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector preorderTraversal(TreeNode* root) {if(root==nullptr)return vector();vector v;stack st;TreeNode*cur=root;while(cur||!st.empty()){//左路节点入栈while(cur){v.push_back(cur->val);st.push(cur);cur=cur->left;}//右路节点的右子树TreeNode*top=st.top();st.pop();cur=top->right;}return v;}};

 

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector inorderTraversal(TreeNode* root) {if(root==nullptr)  return vector();TreeNode*cur=root;stack st;vector v;while(cur||!st.empty()){while(cur){st.push(cur);cur=cur->left;}TreeNode*top=st.top();v.push_back(top->val);st.pop();cur=top->right;}return v;}
};

 

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector postorderTraversal(TreeNode* root) {if(root==nullptr)  return vector();TreeNode*cur=root;TreeNode*prev=nullptr;vector v;stack st;//一个节点不为空的情况下://右子树没有访问,访问右子树//右子树已经访问过了,访问根节点while(cur||!st.empty()){//左路节点入栈while(cur){st.push(cur);cur=cur->left;}TreeNode*top=st.top();//右路节点//如果右为空或者没有访问过if(top->right==nullptr||top->right==prev) {v.push_back(top->val);prev=top;st.pop();} else{cur=top->right;}}return v;}
};

 

 

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...