搜索二叉树的性质
1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关 键码互不相同。
2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。
4. 左右子树都是二叉搜索树。
例如:
第二棵树中,左边的8比根节点5大,右边的4比根节点5小.不满足搜索二叉树的性质。
搜索二叉树的插入
在插入一个数后,依然满足搜索二叉树。
插入分为:
1、为空树,就直接插入。
2、从根节点依次比较,比根节点小,往左树找,比根节点大,往右树找。找到后进行插入。
3、有了这个数就直接返回,不进行插入。
非递归:
bool Insert(const K& key)//非递归插入
{
if (_root == NULL)//为空树,直接插入
{
_root = new Node(key);
return true;
}
Node* cur = _root;
Node* parent = NULL;
while (cur)
{
parent = cur;
if (key > cur->_key)//左树进行找
{
cur = cur->_right;
}
else if (key < cur->_key)//右树进行找
{
cur = cur->_left;
}
else//没找到直接返回
{
return false;
}
}
if (key < parent->_key)
{
parent->_left = new Node(key);
}
else
{
parent->_right = new Node(key);
}
return true;
}
递归:
bool _InsertR(Node*& cur, size_t key)//递归插入
{
if (cur == NULL)
{
cur = new Node(key);
return true;
}
if (key < cur->_key)
{
_InsertR(cur->_left,key);
}
else if(key > cur->_key)
{
_InsertR(cur->_right,key);
}
else
{
return false;
}
}
搜索二叉树的查找
查找分为:
1、空树,直接返回false。
2、与根节点比较,比根节点小,左子树找,比根节点大,右子树找。找到后返回true。
3、没找到,返回false。
非递归:
bool Find(const K& key)//非递归插入
{
if (_root == NULL)//空树
return false;
Node* cur = _root;
while (cur)
{
if (key < cur->_key)//左树找
{
cur = cur->_left;
}
else if (key > cur->_key)//右树找
{
cur = cur->_right;
}
else//找到
{
return true;
}
}
return false;
}
递归:
bool _FindR(Node*& cur, size_t key)//递归查找
{
if (cur == NULL)
return false;
if (key < cur->_key)
{
_FindR(cur->_left, key);
}
else if (key > cur->_key)
{
_FindR(cur->_right, key);
}
else
{
return true;
}
return false;
}
搜索二叉树的删除
在删除一个数后,依然满足搜索二叉树。
删除分为:
1、空树,直接返回。
2、先找这个数,找不到返回。
3、找到后,左子树为空。
4、找到后,右子树为空。
5、找到后,左右都不为空。
大致情况为:
非递归:
bool Remove(const K& key)
{
if (_root == NULL)//空树,删除不了 ,返回false
return false;
Node* cur = _root;
Node* parent = NULL;
Node* del = NULL;
while (cur)
{
if (key < cur->_key)//找的数比根节点小,在左子树上继续找
{
parent = cur;
cur = cur->_left;
}
else if (key > cur->_key)//找的数比根节点大,在右子树上继续找
{
parent = cur;
cur = cur->_right;
}
else//找到了
{
if (cur->_left == NULL)//找到的节点的左为空
{
if (parent == NULL)
_root = cur->_right;
else
{
if (cur == parent->_right)
parent->_right = cur->_right;
else
parent->_left = cur->_right;
}
del = cur;
}
else if (cur->_right == NULL)//找到的节点右为空(包括左右都为空的)
{
if (parent == NULL)
_root = cur->_left;
else
{
if (cur == parent->_left)
parent->_left = cur->_left;
else
parent->_right = cur->_left;
}
del = cur;
}
else//找到的节点左右都不为空,用替换法删除(左子树的最右节点,右子树的最左节点)
{
Node* subNode = cur->_left;
Node* tmp = cur;
while (subNode->_right)
{
tmp = subNode;
subNode = subNode->_right;
}
swap(subNode->_key, cur->_key);
if (subNode == tmp->_left)
tmp->_left = subNode->_right;
else
tmp->_right = subNode->_right;
del = subNode;
}
delete del;
del = NULL;
return true;
}
}
return false;
}
递归:
bool _RemoveR(Node*& cur,size_t key)
{
if (cur == NULL)
{
return false;
}
if (key < cur->_key)
{
_RemoveR(cur->_left, key);
}
else if (key > cur->_key)
{
_RemoveR(cur->_right, key);
}
else
{
Node* del = cur;
if (cur->_left == NULL)
{
cur = cur->_left;
}
else if (cur->_right == NULL)
{
cur = cur->_right;
}
else
{
Node* parent = cur;
Node* subNode = cur->_left;
while (subNode->_right)
{
parent = subNode;
subNode = subNode->_right;
}
swap(subNode->_key, cur->_key);
if (parent->_right = subNode)
parent->_right = subNode->_right;
else
parent->_left = subNode->_right;
del = subNode;
}
delete del;
del = NULL;
return true;
}
return false;
}
代码实现:
"SearchBinaryTree.h"
#pragma once
template <class K>
struct SearchBinaryTreeNode
{
K _key;
SearchBinaryTreeNode<K>* _left;
SearchBinaryTreeNode<K>* _right;
SearchBinaryTreeNode(const K& key)
:_key(key)
, _left(NULL)
, _right(NULL)
{}
};
template <class K>
class SearchBinaryTree
{
typedef SearchBinaryTreeNode<K> Node;
public:
SearchBinaryTree()//无参构造
:_root(NULL)
{}
SearchBinaryTree(K* a, size_t n)//构造函数
{
_root = NULL;
for (size_t i = 0; i < n; ++i)
{
InsertR(a[i]);
}
}
~SearchBinaryTree()
{
_Destory(_root);
}
bool Insert(const K& key)//非递归插入
{
if (_root == NULL)
{
_root = new Node(key);
return true;
}
Node* cur = _root;
Node* parent = NULL;
while (cur)
{
parent = cur;
if (key > cur->_key)
{
cur = cur->_right;
}
else if (key < cur->_key)
{
cur = cur->_left;
}
else
{
return false;
}
}
if (key < parent->_key)
{
parent->_left = new Node(key);
}
else
{
parent->_right = new Node(key);
}
return true;
}
bool InsertR(const K& key)
{
return _InsertR(_root, key);
}
bool Remove(const K& key)
{
if (_root == NULL)//空树,删除不了 ,返回false
return false;
Node* cur = _root;
Node* parent = NULL;
Node* del = NULL;
while (cur)
{
if (key < cur->_key)//找的数比根节点小,在左子树上继续找
{
parent = cur;
cur = cur->_left;
}
else if (key > cur->_key)//找的数比根节点大,在右子树上继续找
{
parent = cur;
cur = cur->_right;
}
else//找到了
{
if (cur->_left == NULL)//找到的节点的左为空
{
if (parent == NULL)
_root = cur->_right;
else
{
if (cur == parent->_right)
parent->_right = cur->_right;
else
parent->_left = cur->_right;
}
del = cur;
}
else if (cur->_right == NULL)//找到的节点右为空(包括左右都为空的)
{
if (parent == NULL)
_root = cur->_left;
else
{
if (cur == parent->_left)
parent->_left = cur->_left;
else
parent->_right = cur->_left;
}
del = cur;
}
else//找到的节点左右都不为空,用替换法删除(左子树的最右节点,右子树的最左节点)
{
Node* subNode = cur->_left;
Node* tmp = cur;
while (subNode->_right)
{
tmp = subNode;
subNode = subNode->_right;
}
swap(subNode->_key, cur->_key);
if (subNode == tmp->_left)
tmp->_left = subNode->_right;
else
tmp->_right = subNode->_right;
del = subNode;
}
delete del;
del = NULL;
return true;
}
}
return false;
}
bool RemoveR(const K& key)
{
return _RemoveR(_root, key);
}
bool Find(const K& key)
{
if (_root == NULL)
return false;
Node* cur = _root;
while (cur)
{
if (key < cur->_key)
{
cur = cur->_left;
}
else if (key > cur->_key)
{
cur = cur->_right;
}
else
{
return true;
}
}
return false;
}
bool FindR(const K& key)
{
return _FindR(_root, key);
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
protected:
bool _FindR(Node*& cur, size_t key)
{
if (cur == NULL)
return false;
if (key < cur->_key)
{
_FindR(cur->_left, key);
}
else if (key > cur->_key)
{
_FindR(cur->_right, key);
}
else
{
return true;
}
return false;
}
bool _RemoveR(Node*& cur,size_t key)
{
if (cur == NULL)
{
return false;
}
if (key < cur->_key)
{
_RemoveR(cur->_left, key);
}
else if (key > cur->_key)
{
_RemoveR(cur->_right, key);
}
else
{
Node* del = cur;
if (cur->_left == NULL)
{
cur = cur->_left;
}
else if (cur->_right == NULL)
{
cur = cur->_right;
}
else
{
Node* parent = cur;
Node* subNode = cur->_left;
while (subNode->_right)
{
parent = subNode;
subNode = subNode->_right;
}
swap(subNode->_key, cur->_key);
if (parent->_right = subNode)
parent->_right = subNode->_right;
else
parent->_left = subNode->_right;
del = subNode;
}
delete del;
del = NULL;
return true;
}
return false;
}
bool _InsertR(Node*& cur, size_t key)
{
if (cur == NULL)
{
cur = new Node(key);
return true;
}
if (key < cur->_key)
{
_InsertR(cur->_left,key);
}
else if(key > cur->_key)
{
_InsertR(cur->_right,key);
}
else
{
return false;
}
}
void _Destory(Node* cur)
{
if (cur == NULL)
return;
_Destory(cur->_left);
_Destory(cur->_right);
delete cur;
cur = NULL;
}
void _InOrder(Node*& cur)
{
if (cur == NULL)
return;
_InOrder(cur->_left);
cout << cur->_key << " ";
_InOrder(cur->_right);
}
protected:
Node* _root;
};
void TestSearchBinaryTree()
{
int a[] = { 5, 1, 2, 8, 3, 9, 4, 6, 7, 0 };
SearchBinaryTree<int> t(a,sizeof(a)/sizeof(a[0]));
}
"Test.cpp"
#include <iostream>
using namespace std;
#include "SearchBinaryTree.h"
int main()
{
TestSearchBinaryTree();
return 0;
}