实现的操作
1.0 插入:找待插入的节点的位置(data<_root->_data左子树,data>_root->_data 右子树)data为待插入节点的值。
2.0 寻找:找节点的位置(data<_root->_data左子树,data>_root->_data 右子树)data为待插入节点的值。
注意:寻找的时候先考虑等于的情况,插入则最后考虑,以上返回值都为bool类型
3.0 删除:先找到待删除节点的位置-->分情况删除(如图)
具体的二叉树:
递归代码如下:
bstree.h
#pragma once
#include<iostream>
using namespace std;
template<class T>
class bstreeNode
{
public:
bstreeNode(const T& data)
: _data(data)
, _left(NULL)
, _right(NULL)
{}
bstreeNode(bstreeNode<T>& node)
: _root->_data(node->data)
, _root->_left(node->_left)
, _root->_right(node->_right)
{}
bstreeNode<T>* _left;
bstreeNode<T>* _right;
T _data;
};
template<class T>
class bstree
{
typedef bstreeNode<T> Node;
typedef Node* PNode;
public:
bstree()
:_root(NULL)
{}
//中序遍历
void InOrderTraverse()
{
_InOrderTraverse(_root);
}
bool Insert(const T& data)
{
return _Insert(_root, data);
}
//查找
bool Find(const T& data)
{
return _Find(_root,data);
}
//删除
bool Delete(const T& data)
{
return _Delete(_root, data);
}
~bstree()
{
_clear(_root);
}
protected:
插入(递归实现)
//bool _Insert(PNode& _root, const T& data) //传引用,修改了_root的值
//{
// if (NULL == _root)//树为空
// {
// _root = new Node(data);
// if (NULL == _root) //new失败
// return false;
// return true;
// }
// else //非空
// {
// if (data < _root->_data)
// _Insert(_root->_left, data);
// else if (_root->_data)
// _Insert(_root->_right, data);
// else //相等的情况
// return false;
// }
//}
//插入(循环实现)
bool _Insert(PNode& _root, const T& data) //传引用,修改了_root的值
{
if (NULL == _root)//树为空
{
_root = new Node(data);
if (NULL == _root) //new失败
return false;
return true;
}
else //非空
{
PNode PCur = _root;
PNode parent = NULL;
while (PCur)
{
if (data < _root->_data)
{
parent = PCur;
PCur = PCur->_left;
}
else if (data> _root->_data)
{
parent = PCur;
PCur = PCur->_right;
}
else //相等的情况
return false;
}
PCur = new Node(data);
if (data > parent->_data)
parent->_right = PCur;
else
parent->_left = PCur;
}
}
//寻找(递归实现)
/*bool _Find(PNode _root, const T& data)
{
if (NULL == _root)
return false;
if (_root->_data == data)
return true;
else if (data< _root->_data)
_Find(_root->_left, data);
else
_Find(_root->_right, data);
}*/
//寻找(循环实现)
bool _Find(PNode _root, const T& data)
{
if (NULL == _root)
return false;
PNode PCur = _root;
while (PCur)
{
if (PCur->_data == data)
return true;
else if (data < PCur->_data)
PCur = PCur->_left;
else
PCur = PCur->_right;
}
if (NULL == PCur)
return false;
else
return true;
}
//删除(递归实现)
//bool _Delete(PNode& _root,const T& data)
//{
// if (NULL == _root)
// return false;
// if (data< _root->_data)
// return _Delete(_root->_left, data);
// else if (data> _root->_data)
// return _Delete(_root->_right, data);
// else //找到了待删除的节点
// {
// PNode PCur = _root;
// if (PCur->_right ==NULL)
// {
// _root = PCur->_left;
// delete PCur;
// PCur = NULL;
// }
// else if (PCur->_left == NULL)
// {
// _root = PCur->_right;
// delete PCur;
// PCur = NULL;
// }
// else
// {
// PCur = PCur->_right;
// while (PCur->_left) //确定待删除节点的右子树的最左侧节点
// {
// PCur = PCur->_left;
// }
// _root->_data = PCur->_data;
// _Delete(_root->_right, PCur->_data);
// }
// return true;
// }
//}
//删除(循环实现)
bool _Delete(PNode& _root, const T& data)
{
PNode PCur = _root;
PNode parent = NULL;
if (NULL == _root)
return false;
while (PCur)
{
if (PCur->_data == data)
break;
else if (data < PCur->_data)
{
parent = PCur;
PCur = PCur->_left;
}
else
{
parent = PCur;
PCur = PCur->_right;
}
}
if (NULL == PCur)
return false;
else
//找到了待删除的节点
{
if (PCur->_right == NULL) //该节点没有左孩子,或者该节点为叶子结点
{
if (PCur == _root) //待删除节点为根节点
_root = PCur->_left;
else //非根
{
if (parent->_left == PCur) //待删除节点为双亲节点的左孩子
parent->_left = PCur->_left;
else //待删除节点为双亲节点的右孩子
parent->_right = PCur->_left;
}
}
else if (PCur->_left == NULL)
{
if (PCur == _root) //待删除节点为根节点
_root = PCur->_right;
else //非根
{
if (parent->_left == PCur) //待删除节点为双亲节点的左孩子
parent->_left = PCur->_right;
else //待删除节点为双亲节点的右孩子
parent->_right = PCur->_right;
}
}
else
{
parent = NULL;
PNode PDel = PCur->_right;
while (PDel->_left) //确定待删除节点的右子树的最左侧节点
{
parent = PDel;
PDel = PDel->_left;
}
PCur->_data = PDel->_data;
if (parent->_left == PDel) //待删除d的替代节点为双亲节点的左孩子
parent->_left = PDel->_right;
if (parent->_right == PDel) //待删除d的替代节点为双亲节点的右孩子
parent->_right = PDel->_right;
PCur = PDel;
}
delete PCur;
PCur = NULL;
return true;
}
}
void _clear(PNode& _Proot)
{
if (NULL == _Proot)
return;
_clear(_Proot->_left);
_clear(_Proot->_right);
delete _Proot;
_Proot = NULL;
}
void _InOrderTraverse(PNode root)
{
if (NULL==root)
return;
_InOrderTraverse(root->_left);
cout << root->_data << " ";
_InOrderTraverse(root->_right);
}
private:
PNode _root;
};
void bstree_test()
{
bstree<int> bst;
int arr[] = { 3, 2, 0, 5, 8, 7 };
int size = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < size; ++i)
{
bst.Insert(arr[i]);
}
bst.InOrderTraverse();
cout << endl;
cout<<bst.Find(6)<<endl;
cout<<bst.Find(2)<<endl;
cout << bst.Delete(5)<< endl;
bst.InOrderTraverse();
cout << endl;
cout << bst.Delete(7) << endl;
bst.InOrderTraverse();
cout << endl;
cout << bst.Delete(8) << endl;
bst.InOrderTraverse();
cout << endl;
cout << bst.Delete(0) << endl;
bst.InOrderTraverse();
cout << endl;
cout << bst.Delete(3) << endl;
bst.InOrderTraverse();
cout << endl;
cout << bst.Delete(2) << endl;
bst.InOrderTraverse();
}
main.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include"bstree.h"
#include<iostream>
using namespace std;
int main()
{
bstree_test();
system("pause");
return 0;
}
结果: