Binary search Tree(二叉搜索树)
二叉搜索树(Binary Search Tree),也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
1. 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2. 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3. 任意节点的左、右子树也分别为二叉搜索树。
4. 没有键值相等的节点(no duplicate nodes)。
插入就相对比较简单了若不存在就创建节点,比根节点大就放在右边,比根节点小就放在左边,若已经存在就不插入。而删除相对考虑的情况就比较多了,主要就是下面几种情况:
实现代码如下:
#pragma once
#include <iostream>
#include <assert.h>
using namespace std;
template <class K>
struct SearchBinaryTreeNode
{
SearchBinaryTreeNode<K>* _left;
SearchBinaryTreeNode<K>* _right;
K _key;
SearchBinaryTreeNode(const K& key)
:_key(key)
, _left(NULL)
, _right(NULL)
{}
};
template<class K>
class SearchBinaryTree
{
typedef SearchBinaryTreeNode<K> Node;
public:
SearchBinaryTree()
:_root(NULL)
{}
bool Insert(const K& key)
{
if (_root==NULL)
{
_root = new Node(key);
return true;
}
Node* parent = NULL;
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;//不存在
}
}
if (key>parent->_key)
{
parent->_right = new Node(key);
}
else
{
parent->_left = new Node(key);
}
return true;
}
Node* Find(const K& key)
{
Node* cur = _root;
while(cur)
{
if (cur->_key > key)
{
cur = cur->_left;
}
else if (cur->_key<key)
{
cur = cur->_right;
}
else
{
cout << "找到:" << key << endl;
return cur;
}
}
cout << "未找到" << endl;
return cur;
}
bool Remove(const K& key)
{
Node* cur = _root;
Node* parent = NULL;
Node* del = NULL;
while (cur)
{
if (cur->_key<key)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else //找到需要删除的结点了
{
if (NULL == cur->_left)// 左为空
{
del = cur;
if (NULL == parent)//中有一个节点(根节点)
{
_root = _root->_right;
}
else if (parent->_left==cur)// cur是parent左节点
{
parent->_left = cur->_right;
}
else //右节点
{
parent->_right = cur->_right;
}
}
else if (NULL == cur->_right)//右为空
{
del = cur;
if (NULL == parent)
{
_root = _root->_left;
}
else if (parent->_right==cur) // 右节点
{
parent->_right = cur->_left;
}
else
{
parent->_left = cur->_left;
}
}
else //左右都不为空
{
Node* SubRight = cur->_right;
Node* parent = cur;
while (SubRight->_left)
{
parent = SubRight;
SubRight = SubRight->_left;
}
del = SubRight;
cur->_key = SubRight->_key;
if (parent->_left=SubRight)
{
parent->_left = SubRight->_right;
}
else
{
parent->_right = SubRight->_right;
}
}
delete del;
return true;
}
}
return false;
}
//递归插入
void InsertR(const K& key)
{
_InsertR(_root, key);
}
//递归查找
Node* FindR(const K& key)
{
return _FindR(_root,key);
}
//递归删除
bool RemoveR(const K& key)
{
return _RemoveR(_root,key);
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
protected:
bool _InsertR(Node* &root, const K& key)
{
if (root == NULL)
{
root = new Node(key);
}
if (root->_key > key)
{
return _InsertR(root->_left, key);
}
else if (root->_key < key)
{
return _InsertR(root->_right, key);
}
else
{
return false;
}
return true;
}
Node* _FindR(Node* root, const K& key)
{
if (root == NULL)
{
cout << "未找到" << endl;
return NULL;
}
else{
if (root->_key > key)
{
return _FindR(root->_left, key);
}
else if (root->_key < key)
{
return _FindR(root->_right, key);
}
else {
cout << "找到:" << root->_key << endl;
return root;
}
}
}
bool _RemoveR(Node* &root, const K& key)
{
if (root==NULL)
{
return false;
}
if (root->_key>key)
{
return _RemoveR(root->_left, key);
}
else if (root->_key<key)
{
return _RemoveR(root->_right, key);
}
else
{
Node* del = root;
if (root->_left==NULL) // 替换法
{
root = root->_right;
delete del;
}
else if (root->_right==NULL)
{
root = root->_left;
delete del;
}
else
{
Node* left= root->_right;
while (left->_left)
{
root->_key = left->_key;
_RemoveR(root->_right, left->_key);
}
return true;
}
}
}
void _InOrder(Node* root)
{
if (root==NULL)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
private:
Node* _root;
};
void Test1()
{
int a[] = {5,3,4,1,7,8,2,6,0,9};
SearchBinaryTree<int> t;
for (size_t i = 0; i < sizeof(a) / sizeof(a[0]);i++)
{
t.Insert(a[i]);
}
t.InOrder();
t.Find(2);
t.Remove(0);
t.Remove(1);
t.Remove(2);
t.Remove(3);
t.Remove(4);
t.Remove(5);
t.Remove(6);
t.Remove(7);
t.Remove(8);
t.Remove(9);
t.Remove(0);
t.Remove(1);
t.InOrder();
}
void Test2()
{
int a[] = {5,3,4,1,7,8,2,6,0,9};
SearchBinaryTree<int> t;
for (size_t i = 0; i < sizeof(a) / sizeof(a[0]);i++)
{
//t.Insert(a[i]);
t.InsertR(a[i]);
}
t.InOrder();
t.Find(2);
t.Remove(0);
t.RemoveR(1);
t.RemoveR(2);
t.RemoveR(3);
t.RemoveR(4);
t.RemoveR(5);
t.RemoveR(6);
t.RemoveR(7);
t.RemoveR(8);
t.RemoveR(9);
t.RemoveR(0);
t.RemoveR(1);
t.InOrder();
}