二叉搜索树:
1.每个节点都有一个关键码(key)作为搜索依据,关键码互不相同。
2.左子树的所有关键码都小于根节点的关键码。
3.右子树的所有关键码都大于根节点的关键码。
4.左右子树都是二叉搜索树。
删除key:左为空,右为空,左右都不空
1)左为空:cur的右树链到父节点
2)右为空:cur的左树链到父节点
3)左右都不空:找右树最左节点或左树最右节点,将找到的节点与cur交换后删除它。
二叉搜索树的增、删、查(非递归及递归)程序代码如下:
#pragma once
#include<string>
注意:考虑边界问题_root 、左右子树问题(非递归、递归)、记住判空处理
template<class K,class V>
struct BSTNode
{
BSTNode<K, V>* _left; //左子数
BSTNode<K, V>* _right; //右子树
K _key;
V _value;
//构造函数
BSTNode(const K& key, const V& value)
:_left(NULL)
, _right(NULL)
, _key(key)
, _value(value)
{}
};
template<class K, class V>
class BSTree
{
typedef BSTNode<K, V> Node;
public:
BSTree()
:_root(NULL)
{}
public:
//bool Insert(const K& key, const V& value);
//bool Remove(const K& key);
//Node* Find(const K& key);
//bool Insert_R(const K& key, const V& value);
//bool Remove_R(const K& key, const V& value);
//Node* Find_R(const K& key);
bool Insert(const K& key, const V& value)
{
if(_root == NULL)
_root = new Node(key, value);
Node* cur = _root;
while(cur)
{
if(key < cur->_key) //key小,插入左子树
{
if(cur->_left == NULL)
cur->_left = new Node(key, value);
else
cur = cur->_left;
}
else if(key > cur->_key) //key大,插入右子树
{
if(cur->_right == NULL)
cur->_right = new Node(key, value);
else
cur = cur->_right;
}
else //key关键码互不相同
return false;
}
return true;
}
删除//
边界条件判断(无节点,一个节点)
找key值,记录parent。
删除key,分三种情况(左为空,右为空,左右都不为空)
左右节点都存在,找到右树的最左节点或者左树的最右节点,
将找到的节点与cur交换后再删除找到的节点
bool Remove(const K& key)
{
//无节点
if(_root == NULL)
return false;
//一个节点 _root
if(_root->_left == NULL&&_root->_right == NULL)
{
if(key == _root->_key)
{
delete _root;
_root = NULL;
return true;
}
else
return false;
}
Node* cur = _root;
Node* parent = NULL;
while(cur)
{ //找key值,记录parent
if(key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else if(key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
删除key,分三种情况(左为空,右为空,左右都不为空)
else
{
Node*del=cur;
if(cur->_left == NULL) //将cur的右子树链到父节点
{
//注意parent可能为空
if(parent == NULL)
{
_root = cur->_right;
}
else
{
if(cur = parent->_left)
parent->_left = cur->_right;
else
parent->_right = cur->_right;
}
}
else if(cur->_right == NULL) //将cur的左子树链到父节点
{
if(parent == NULL)
{
_root = cur->_left;
}
else
{
if(cur = parent->_left)
parent->_left = cur->_left;
else
parent->_right = cur->_left;
}
}
左右节点都存在,找到右树的最左节点或者左树的最右节点
将找到的节点与cur交换后再删除找到的节点
else
{
parent = cur;
//右树的最左节点firstLeft
Node* firstLeft = cur->_right;
while(firstLeft->_left)
{
parent = firstLeft;
firstLeft = firstLeft->_left;
}
swap(firstLeft->_key, cur->_key);
swap(firstLeft->_value, cur->_value);
del = firstLeft;
//因为左右节点都存在,所以parent不为空
//firstLeft 左节点为空,右节点可能存在
if(firstLeft == parent->_left)
parent->_left = firstLeft->_right;
else
parent->_right = firstLeft->_right;
} /*找到firstLeft代替del*/
delete del;
return true;
}
}//while end
return false;
}
//查找
Node* Find(const K& key)
{
if(_root == NULL)
return NULL;
Node* cur = _root;
while(cur)
{
if(key < cur->_key) //在左子树查找
{
cur = cur->_left;
}
else if(key>cur->_key) //在右子树查找
{
cur = cur->_right;
}
else
{
return cur;
}
}
return NULL;
}
/递归实现增删查
bool Insert_R(const K& key, const V& value)
{
return _Insert_R(_root, key, value);
}
bool Remove_R(const K& key)
{
return _Remove_R(_root, key);
}
Node* Find_R(const K& key)
{
return _Find_R(_root, key);
}
//中序遍历
void InOrder()
{
return _InOrder(_root);
}
bool Empty()
{
if(_root == NULL)
{
return true;
}
return false;
}
protected:
void _InOrder(Node* root)
{
if(root == NULL)
return;
_InOrder(root->_left);
//cout << root->_key << " " << endl;
cout << "key:" << root->_key << " ,value:" << root->_value<< endl;
_InOrder(root->_right);
}
注意:root参数应为引用& 每次递归的root即为上一次的root->_left或者root->_right
bool _Insert_R(Node*& root, const K& key, const V& value)
{
if(root == NULL)
{
root = new Node(key, value);
return true;
}
if(key < root->_key)
{
return _Insert_R(root->_left, key, value);
}
else if(key>root->_key)
{
return _Insert_R(root->_right, key, value);
}
else
{
return false;
}
}
//查找
Node* _Find_R(Node*& root, const K& key)
{
if(root == NULL)
return NULL;
if(key < root->_key)
{
return _Find_R(root->_left, key);
}
else if(key>root->_key)
{
return _Find_R(root->_right, key);
}
else
{
return root;
}
}
//删除
bool _Remove_R(Node*& root, const K& key)
{
if(root == NULL)
return false;
if(key < root->_key)
{
return _Remove_R(root->_left, key);
}
else if(key > root->_key)
{
return _Remove_R(root->_right, key);
}
///删除key
以引用root作参数,root相当于上一层的root->_left或者root->_right
else
{
Node*del = root;
if(root->_left == NULL)
{
root = root->_right;
delete del;
return true;
}
else if(root->_right == NULL)
{
root = root->_left;
delete del;
return true;
}
///左右节点都不为空
else
{
//右子树的最左节点
Node* firstLeft = root->_right;
while(firstLeft->_left)
{
firstLeft = firstLeft->_left;
}
swap(firstLeft->_key, root->_key);
swap(firstLeft->_value, root->_value);
//_Remove_R(firstLeft, key);//错误,firstLeft是临时变量不能作为递归的参数
_Remove_R(root->_right, key);
}
}///删除key end
return false;
}
protected:
Node* _root;
};
测试代码:
void TestBSTree()
{
BSTree<int, int> bst;
bst.Insert(5, 1);
bst.Insert(3, 1);
bst.Insert(4, 1);
bst.Insert(1, 1);
bst.Insert(7, 1);
bst.Insert(8, 1);
bst.Insert(2, 1);
bst.Insert(6, 1);
bst.Insert(0, 1);
bst.Insert(9, 1);
bst.InOrder();
cout << "? " << bst.Find(1)->_key<< endl;
cout << "? " << bst.Find(8)->_key<< endl;
cout << "? " << bst.Find(22)<< endl;
bst.Remove(1);
bst.Remove(2);
bst.Remove(3);
bst.Remove(4);
bst.Remove(5);
bst.Remove(6);
bst.Remove(7);
bst.Remove(8);
bst.Remove(9);
bst.Remove(0);
if(bst.Empty())
cout << "此二叉搜索树为空" << endl;
bst.InOrder();
}
void TestBSTree_R() //递归
{
BSTree<int, int> bst;
bst.Insert_R(5, 1);
bst.Insert_R(3, 1);
bst.Insert_R(4, 1);
bst.Insert_R(1, 1);
bst.Insert_R(7, 1);
bst.Insert_R(8, 1);
bst.Insert_R(2, 1);
bst.Insert_R(6, 1);
bst.Insert_R(0, 1);
bst.Insert_R(9, 1);
bst.InOrder();
cout << "? " << bst.Find(1)->_key << endl;
cout << "? " << bst.Find(8)->_key << endl;
cout << "? " << bst.Find(22) << endl;
/*
bst.Remove_R(1);
bst.Remove_R(2);
bst.Remove_R(3);
bst.Remove_R(4);
*/
bst.Remove_R(5);
bst.Remove_R(6);
bst.Remove_R(7);
bst.Remove_R(8);
bst.Remove_R(9);
bst.Remove_R(0);
if(bst.Empty())
cout << "此二叉搜索树为空" << endl;
bst.InOrder();
}
void TestBSTree_string() // int string
{
BSTree<int, string> bst;
bst.Insert(5, "zhou");
bst.Insert(3, "sun");
bst.Insert(4, "li");
bst.Insert(1, "zhao");
bst.Insert(7, "zheng");
bst.Insert(8, "wang");
bst.Insert(2, "qian");
bst.Insert(6, "wu");
bst.Insert(0, "baijiaxing");
bst.Insert(9, "feng");
bst.InOrder();
cout << "? " << bst.Find(1)->_key << endl;
cout << "? " << bst.Find(8)->_key << endl;
cout << "? " << bst.Find(22) << endl;
//bst.Remove(0);
//bst.Remove(1);
//bst.Remove(2);
//bst.Remove(3);
//bst.Remove(4);
bst.Remove(5);
bst.Remove(6);
bst.Remove(7);
bst.Remove(8);
bst.Remove(9);
if(bst.Empty())
cout << "此二叉搜索树为空" << endl;
bst.InOrder();
}
本文出自 “娜些维度的雪” 博客,请务必保留此出处http://1536262434.blog.51cto.com/10731069/1790713