二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树
int a [] = {5,3,4,1,7,8,2,6,0,9};
2. 二叉搜索树的插入
插入的具体过程如下:
a. 树为空,则直接插入
b. 树不空,按二叉搜索树性质查找插入位置,插入新节点
3. 二叉搜索树的删除
4. 首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情况:
a. 要删除的结点无孩子结点
b. 要删除的结点只有左孩子结点
c. 要删除的结点只有右孩子结点
d. 要删除的结点有左、右孩子结点
看起来有待删除节点有4中情况,实际情况a可以与情况b或者c合并起来,因此真正的删除过程如下:
#pragma once
#include
using namespace std;
template<class K>
struct BSTreeNode
{
BSTreeNode(const K& key)
{
_left = _right = nullptr;
_key = key;
}
BSTreeNode* _left;
BSTreeNode* _right;
K _key;
};
template<class K>
class BSTree
{
public:
typedef BSTreeNode<K> Node;
BSTree()
:_root(nullptr)
{}
Node* FindR(const K& key)
{
return _FindR(_root, key);
}
bool Find(const K& key)
{
Node* cur = _root;
while (cur != nullptr)
{
if (cur->_key < key)
{
cur = cur->_right;
}
else if (cur->_key > key)
{
cur = cur->_left;
}
else
{
return true;
}
}
return false;
}
bool InsertR(const K& key)
{
return _InsertR(_root, key);
}
bool Insert(const K& key)
{
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
else
{
Node* cur = _root;
Node* parent = nullptr;
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为空
if (parent->_key < key)
{
parent->_right = new Node(key);
}
else
{
parent->_left = new Node(key);
}
return true;
}
}
bool EraseR(const K& key)
{
return _EraseR(_root, key);
}
bool Erase(const K& key)
{
if (_root == nullptr)
{
return false;
}
Node* cur = _root;
Node* parent = nullptr;
while (cur)
{
if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else
{
//找到了
if (cur->_left == nullptr)
{
if (cur == _root)
{
_root = _root->_right;
}
else if (parent->_left == cur)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
delete cur;
}
else if (cur->_right == nullptr)
{
if (cur == _root)
{
_root = cur->_left;
}
if (parent->_left == cur)
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
delete cur;
}
else//左右节点都在
{
Node* min = cur->_right;
Node* min_parent = cur;
while (min->_left != nullptr)
{
min_parent = min;
min = min->_left;
}
cur->_key = min->_key;//替换
if (min_parent->_left == min)
{
min_parent->_left = min->_right;
}
else
{
min_parent->_right = min->_right;
}
delete min;
}
return true;
}
}
return false;
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
private:
void _InOrder(Node* root)
{
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
Node* _FindR(Node* root, const K& key)
{
if (root == nullptr)
{
return nullptr;
}
else
{
if (root->_key < key)
{
_FindR(root->_right, key);
}
else if(root->_key > key)
{
_FindR(root->_left, key);
}
else
{
return root;
}
}
}
bool _InsertR(Node*& root, const K& key)
{
if (root == nullptr)
{
root = new Node(key);
return true;
}
if (root->_key < key)
{
_InsertR(root->_right, key);
}
else if (root->_key > key)
{
_InsertR(root->_left, key);
}
return false;
}
bool _EraseR(Node*& root, const K& key)
{
if (root == nullptr)
{
return false;
}
if (root->_key < key)
{
_EraseR(root->_right, key);
}
else if (root->_key > key)
{
_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 != nullptr)
{
min = min->_left;
}
swap(root->_key, min->_key);
//_EraseR(root, key);
return _EraseR(root->_right, key);
}
delete del;
}
}
Node* _root;
};
#pragma once
#include
#include
using namespace std;
namespace ts
{
template<class K, class V>
struct BSTreeNode
{
BSTreeNode(const K& key, const V& value)
{
_left = _right = nullptr;
_key = key;
_value = value;
}
BSTreeNode* _left;
BSTreeNode* _right;
K _key;
V _value;
};
template< class K, class V>
class BSTree
{
public:
typedef BSTreeNode<K, V> Node;
BSTree()
:_root(nullptr)
{}
Node* Find(const K& key)
{
Node* cur = _root;
while (cur != nullptr)
{
if (cur->_key < key)
{
cur = cur->_right;
}
else if (cur->_key > key)
{
cur = cur->_left;
}
else
{
return cur;
}
}
return nullptr;
}
bool Insert(const K& key, const V& value)
{
if (_root == nullptr)
{
_root = new Node(key, value);
return true;
}
else
{
Node* cur = _root;
Node* parent = nullptr;
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为空
if (parent->_key < key)
{
parent->_right = new Node(key, value);
}
else
{
parent->_left = new Node(key, value);
}
return true;
}
}
bool Erase(const K& key)
{
if (_root == nullptr)
{
return false;
}
Node* cur = _root;
Node* parent = nullptr;
while (cur)
{
if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else
{
//找到了
if (cur->_left == nullptr)
{
if (cur == _root)
{
_root = _root->_right;
}
else if (parent->_left == cur)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
delete cur;
}
else if (cur->_right == nullptr)
{
if (cur == _root)
{
_root = cur->_left;
}
if (parent->_left == cur)
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
delete cur;
}
else//左右节点都在
{
Node* min = cur->_right;
Node* min_parent = cur;
while (min->_left != nullptr)
{
min_parent = min;
min = min->_left;
}
cur->_key = min->_key;//替换
cur->_value = min->_value;
if (min_parent->_left == min)
{
min_parent->_left = min->_right;
}
else
{
min_parent->_right = min->_right;
}
delete min;
}
return true;
}
}
return false;
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
private:
void _InOrder(Node* root)
{
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " " << root->_value << endl;;
_InOrder(root->_right);
}
Node* _root;
};
}
插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。
对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的
深度的函数,即结点越深,则比较次数越多。
但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树:
最优情况下,二叉搜索树为完全二叉树,其平均比较次数为:log2^N
最差情况下,二叉搜索树退化为单支树,其平均比较次数为:N/2
问题:如果退化成单支树,二叉搜索树的性能就失去了。那能否进行改进,不论按照什么次序插入关键码,都可以是二叉搜索树的性能最佳?
/**
* 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:
void _tree2str(TreeNode* root, string& s)
{
if(root == nullptr)
{
return;
}
s += to_string(root->val);
if(root->left || root->right)//root的右边为空的时候,左边不能为空
{
s += '(';
_tree2str(root->left, s);
s += ')';
}
if(root->right)
{
s += '(';
_tree2str(root->right, s);
s += ')';
}
}
string tree2str(TreeNode* root)
{
string s;
_tree2str(root, s);
return s;
}
};
/**
* 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<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> vv;
queue<TreeNode*> q;
int levelSize = 0;//记录每一层的个数
if(root == nullptr)
{
return vv;
}
q.push(root);
levelSize = 1;
while(!q.empty())
{
vector<int> v;
while(levelSize--)//一层一层的出
{
TreeNode* front = q.front();
v.push_back(front->val);
q.pop();
if(front->left)
q.push(front->left);
if(front->right)
q.push(front->right);
}
vv.push_back(v);
levelSize = q.size();
}
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<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> vv;
queue<TreeNode*> q;
int levelSize = 0;
if(root == nullptr)
{
return vv;
}
q.push(root);
levelSize = 1;
while(!q.empty())
{
vector<int> v;
while(levelSize--)
{
TreeNode* front = q.front();
v.push_back(front->val);
q.pop();
if(front->left)
q.push(front->left);
if(front->right)
q.push(front->right);
}
vv.push_back(v);
levelSize = q.size();
}
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 {
//查找节点的路径
bool FindPath(TreeNode* root, TreeNode* x, stack<TreeNode*>& path)
{
if(root == nullptr)
return false;
path.push(root);
if(root == x)
return true;
if(FindPath(root->left, x, path))
return true;
else if(FindPath(root->right, x, path))
return true;
path.pop();
return false;
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
stack<TreeNode*> pPath;
stack<TreeNode*> qPath;
FindPath(root, p, pPath);//将p的路径保存在pPath中
FindPath(root, q, qPath);//将q的路径保存在qPath总
//将路径长度变为相同
while(pPath.size() != qPath.size())
{
if(pPath.size() < qPath.size())
qPath.pop();
else
pPath.pop();
}
//同时查找,判断是否相同
while(!pPath.empty())
{
if(pPath.top() == qPath.top())
return pPath.top();
pPath.pop();
qPath.pop();
}
return nullptr;
}
};
方法二:
/**
* 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<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> vv;
queue<TreeNode*> q;
int levelSize = 0;
if(root == nullptr)
{
return vv;
}
q.push(root);
levelSize = 1;
while(!q.empty())
{
vector<int> v;
while(levelSize--)
{
TreeNode* front = q.front();
v.push_back(front->val);
q.pop();
if(front->left)
q.push(front->left);
if(front->right)
q.push(front->right);
}
vv.push_back(v);
levelSize = q.size();
}
reverse(vv.begin(), vv.end());
return vv;
}
};
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
void InOrder(TreeNode* cur, TreeNode*& prev)
{
if(cur == nullptr)
return;
InOrder(cur->left, prev);
//链接
if(prev == nullptr)
prev = cur;
else
{
prev->right = cur;
cur->left = prev;
prev = cur;
}
InOrder(cur->right, prev);
}
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree) {
if(pRootOfTree == nullptr)
return nullptr;
TreeNode* prev = nullptr;
InOrder(pRootOfTree, prev);
//找头结点
TreeNode* head = pRootOfTree;
while(head->left)
{
head = head->left;
}
return head;
}
};
/**
* 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<int>& preorder, vector<int>& inorder, int& prei, int inbegin, int inend )
{
if(inbegin > inend)
return nullptr;
TreeNode* root = new TreeNode(preorder[prei]);
int rooti = inbegin;
while(rooti <= inend)
{
if(preorder[prei] == inorder[rooti])
break;
else
++rooti;
}
++prei;
//[inbegin, rooti-1] [rooti+1, inend]
root->left = _buildTree(preorder, inorder, prei, inbegin, rooti-1);
root->right = _buildTree(preorder, inorder, prei, rooti+1, inend);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int prei = 0;
return _buildTree(preorder, inorder, prei, 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:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> v;
stack<TreeNode*> s;
TreeNode* cur = root;
while(cur || !s.empty())
{
while(cur)
{
v.push_back(cur->val);
s.push(cur);
cur = cur->left;
}
TreeNode* top = s.top();
s.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<int> inorderTraversal(TreeNode* root) {
vector<int> v;
stack<TreeNode*> s;
TreeNode* cur = root;
while(cur || !s.empty())
{
while(cur)
{
s.push(cur);
cur = cur->left;
}
TreeNode* top = s.top();
s.pop();
v.push_back(top->val);
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<int> postorderTraversal(TreeNode* root)
{
vector<int> v;
stack<TreeNode*> s;
TreeNode* cur = root;
TreeNode* prev = nullptr;
while(cur || !s.empty())
{
while(cur)
{
s.push(cur);
cur = cur->left;
}
TreeNode* top = s.top();
if(top->right == nullptr || top->right == prev)
{
v.push_back(top->val);
prev = top;
s.pop();
}
else
{
cur = top->right;
}
}
return v;
}
};