二叉搜索树
目录
一、插入
二、查询
三、删除
一、插入
思路
其实就是查找的过程,一直找到空指针,就把空指针赋值为要插入的数据并返回
true
,如果查到了相等的元素,就返回false
代码实现
#include <iostream>
using namespace std;
template <class K, class V>
struct BSTreeNode
{
BSTreeNode(const K& k, const V& v) : lchild(NULL), rchild(NULL), key(k), value(v) {}
BSTreeNode* lchild;
BSTreeNode* rchild;
K key;
V value;
};
template <class K, class V>
class BST
{
typedef BSTreeNode<K, V> Node;
public:
BST() :m_Root(NULL) {}
bool Insert(const K& k, const V& v)
{
return Insert_(this->m_Root, k, v);
}
bool Insert_(Node*& root, const K& k, const V& v)
{
if (!root)
{
root = new Node(k, v);
return true;
}
else
{
if (root->key > k)
{
return Insert_(root->lchild, k, v);
}
else if (root->key < k)
{
return Insert_(root->rchild, k, v);
}
else
{
return false;
}
}
}
//释放在堆区开辟的内存空间
void clear()
{
clear_(this->m_Root);
}
void clear_(Node* root)
{
//基线条件,当根结点为空使说明当前结点清除完毕,返回
if (!root)
{
return;
}
else
{
//先清除左子树
clear_(root->lchild);
//再清除右子树
clear_(root->rchild);
//最后清除根结点
delete root;
}
}
private:
Node* m_Root;
};
int main()
{
BST<int,int> BSTree;
if (BSTree.Insert(5, 1))
{
cout << "插入成功" << endl;
}
else
{
cout << "插入失败" << endl;
}
if (BSTree.Insert(5, 2))
{
cout << "插入成功" << endl;
}
else
{
cout << "插入失败" << endl;
}
BSTree.clear();//释放在堆区开辟的内存空间
system("pause");
return 0;
}
运行结果:
返回目录
二、查询
思路
先判断根结点是否为空,如果为空就返回
NULL
,如果根结点大于目标结点,递归调用根结点的左子树为根结点;如果根结点小于目标结点, 递归调用根结点的右子树为根结点;如果根结点等于目标结点,返回该结点
代码实现
#include <iostream>
using namespace std;
template <class K, class V>
struct BSTreeNode
{
BSTreeNode(const K& k, const V& v) : lchild(NULL), rchild(NULL), key(k), value(v) {}
BSTreeNode* lchild;
BSTreeNode* rchild;
K key;
V value;
};
template <class K, class V>
class BST
{
typedef BSTreeNode<K, V> Node;
public:
BST() :m_Root(NULL) {}
bool Insert(const K& k, const V& v)
{
return Insert_(this->m_Root, k, v);
}
bool Insert_(Node*& root, const K& k, const V& v)
{
if (!root)
{
root = new Node(k, v);
return true;
}
else
{
if (root->key > k)
{
return Insert_(root->lchild, k, v);
}
else if (root->key < k)
{
return Insert_(root->rchild, k, v);
}
else
{
return false;
}
}
}
Node* Find(const K& k)
{
return Find_(this->m_Root, k);
}
Node* Find_(Node* root, const K& k)
{
if (!root)
{
return NULL;
}
else
{
if (root->key > k)
{
return Find_(root->lchild, k);
}
else if (root->key < k)
{
return Find_(root->rchild, k);
}
else
{
return root;
}
}
}
//释放在堆区开辟的内存空间
void clear()
{
clear_(this->m_Root);
}
void clear_(Node* root)
{
//基线条件,当根结点为空使说明当前结点清除完毕,返回
if (!root)
{
return;
}
else
{
//先清除左子树
clear_(root->lchild);
//再清除右子树
clear_(root->rchild);
//最后清除根结点
delete root;
}
}
private:
Node* m_Root;
};
int main()
{
BST<int, int> BSTree;
BSTree.Insert(5, 1);
BSTree.Insert(6, 2);
BSTreeNode<int, int>* ret = BSTree.Find(6);
if (!ret)
{
cout << "未查到" << endl;
}
else
{
cout << "查找到的元素value:" << ret->value << endl;
}
BSTree.clear();
system("pause");
return 0;
}
运行结果:
返回目录
三、删除
思路
情况一:
当要删除的结点的左右结点至少有一个为空的情况,就将当前结点的指针改为左右结点中的一个并将自身开辟的空间的空间释放
情况二:
当要删除的结点左右结点都不为空时,首先将该结点的数据和它中序遍历右边的第一个结点互换数据,然后必定会转换为第一种情况,它的右边第一个结点的左节点必定为空
代码实现
#include <iostream>
using namespace std;
template <class K, class V>
struct BSTreeNode
{
BSTreeNode(const K& k, const V& v) : lchild(NULL), rchild(NULL), key(k), value(v) {}
BSTreeNode* lchild;
BSTreeNode* rchild;
K key;
V value;
};
template <class K, class V>
class BST
{
typedef BSTreeNode<K, V> Node;
public:
BST() :m_Root(NULL) {}
bool Insert(const K& k, const V& v)
{
return Insert_(this->m_Root, k, v);
}
bool Insert_(Node*& root, const K& k, const V& v)
{
if (!root)
{
root = new Node(k, v);
return true;
}
else
{
if (root->key > k)
{
return Insert_(root->lchild, k, v);
}
else if (root->key < k)
{
return Insert_(root->rchild, k, v);
}
else
{
return false;
}
}
}
Node* Find(const K& k)
{
return Find_(this->m_Root, k);
}
Node* Find_(Node* root, const K& k)
{
if (!root)
{
return NULL;
}
else
{
if (root->key > k)
{
return Find_(root->lchild, k);
}
else if (root->key < k)
{
return Find_(root->rchild, k);
}
else
{
return root;
}
}
}
bool remove(const K& k)
{
return remove_(this->m_Root, k);
}
bool remove_(Node*& root, const K& k)
{
if (!root)
{
return false;
}
else
{
if (root->key > k)
{
return remove_(root->lchild, k);
}
else if (root->key < k)
{
return remove_(root->rchild, k);
}
else
{
Node* del;
if (!root->lchild)
{
del = root;
root = root->rchild;
delete del;
del = NULL;
return true;
}
else if (!root->rchild)
{
del = root;
root = root->lchild;
delete del;
del = NULL;
return true;
}
else
{
Node* rightfirst = root->rchild;
while (rightfirst->lchild)
{
rightfirst = rightfirst->lchild;
}
swap(rightfirst->key, root->key);
swap(rightfirst->value, root->value);
remove_(root->rchild, k);
}
}
}
}
//二叉搜索树的中序遍历
void inorderBST()
{
inorderBST_(this->m_Root);
cout << endl;
}
void inorderBST_(Node* root)
{
if (!root)
{
return;
}
inorderBST_(root->lchild);
cout << root->key << " ";
inorderBST_(root->rchild);
}
//释放在堆区开辟的内存空间
void clear()
{
clear_(this->m_Root);
}
void clear_(Node* root)
{
//基线条件,当根结点为空使说明当前结点清除完毕,返回
if (!root)
{
return;
}
else
{
//先清除左子树
clear_(root->lchild);
//再清除右子树
clear_(root->rchild);
//最后清除根结点
delete root;
}
}
private:
Node* m_Root;
};
int main()
{
BST<int, int> BSTree;
BSTree.Insert(6, 2);
BSTree.Insert(8, 2);
BSTree.Insert(7, 2);
BSTree.Insert(4, 2);
BSTree.Insert(5, 2);
BSTree.Insert(9, 2);
BSTree.inorderBST();
BSTree.remove(6);
BSTree.inorderBST();
BSTree.clear();
system("pause");
return 0;
}
运行结果: