一:背景
二叉排序树又称“二叉查找树”、“二叉搜索树”。
二叉排序树:或者是一棵空树,或者是具有下列性质的二叉树:1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3. 它的左、右子树也分别为二叉排序树。
例如下图就是一个二叉排序树:
二:分析
首先先定义好节点结构,代码如下:
typedef struct Node
{
int m_key;
Node* m_lChild;
Node* m_rChild;
Node(int key)
{
m_key = key;
m_lChild = m_rChild = nullptr;
}
}* PNode;
1.插入操作
/* 插入操作 */
bool Add(int key, PNode & p)
{
if (p == nullptr)
{
p = new Node(key);
return true;
}
else
{
if (key == p->m_key)
return false;
else if (key < p->m_key)
return Add(key, p->m_lChild);
else
return Add(key, p->m_rChild);
}
}
2.删除操作
/* 删除操作 */
bool Delete(int key, PNode & p)
{
if (p == nullptr)
return false;
else
{
if (key == p->m_key)
{
if (p->m_lChild&&p->m_rChild)//左右孩子都存在
{
//若是左右孩子都在,我们的策略是删除该节点右子树下的最小节点,当然在这之前需要把这个最小节点值赋予该节点
PNode t = p->m_rChild;
while (t->m_lChild)
t = t->m_lChild;
p->m_key = t->m_key;//这个最小节点值赋予该节点
Delete(p->m_key, p->m_rChild);//删除该节点右子树下的最小节点
}
else if (!p->m_lChild && !p->m_rChild)//左右孩子都不存在
{
PNode t = p;
p = nullptr;
delete t;
return true;
}
else
{
PNode t = p;
p = (p->m_lChild == nullptr) ? p->m_rChild : p->m_lChild;
delete t;
return true;
}
}
else if (key < p->m_key)
return Delete(key, p->m_lChild);
else
return Delete(key, p->m_rChild);
}
}
3.查找
/* 查找 */
bool Find(int key, PNode & p)
{
if (p == nullptr)
return false;
else
{
if (key == p->m_key)
return true;
else if (key < p->m_key)
return Find(key, p->m_lChild);
else
return Find(key, p->m_rChild);
}
}
4.层次遍历
/* 求以该节点为树根的树的高度 */
int Height(PNode & p)
{
if (p == nullptr)
return 0;
else
return max(Height(p->m_lChild), Height(p->m_rChild)) + 1;
}
/* 层次遍历 */
void PrintTheLevel(PNode & p, int level)
{
if (!p || level <= 0)
return;
if (level == 1)
{
cout << p->m_key << " ";
return;
}
PrintTheLevel(p->m_lChild, level - 1);
PrintTheLevel(p->m_rChild, level - 1);
}
void LevelOrder(PNode & p)
{
int depth = Height(p);
for (int i = 1; i <= depth; i++)
{
PrintTheLevel(p, i);
cout << endl;
}
cout << endl;
}
三:完整代码
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#include<iostream>
#include<algorithm>
using namespace std;
typedef struct Node
{
int m_key;
Node* m_lChild;
Node* m_rChild;
Node(int key)
{
m_key = key;
m_lChild = m_rChild = nullptr;
}
}* PNode;
PNode root = nullptr;
/* 插入操作 */
bool Add(int key, PNode & p)
{
if (p == nullptr)
{
p = new Node(key);
return true;
}
else
{
if (key == p->m_key)
return false;
else if (key < p->m_key)
return Add(key, p->m_lChild);
else
return Add(key, p->m_rChild);
}
}
/* 删除操作 */
bool Delete(int key, PNode & p)
{
if (p == nullptr)
return false;
else
{
if (key == p->m_key)
{
if (p->m_lChild&&p->m_rChild)//左右孩子都存在
{
//若是左右孩子都在,我们的策略是删除该节点右子树下的最小节点,当然在这之前需要把这个最小节点值赋予该节点
PNode t = p->m_rChild;
while (t->m_lChild)
t = t->m_lChild;
p->m_key = t->m_key;//这个最小节点值赋予该节点
Delete(p->m_key, p->m_rChild);//删除该节点右子树下的最小节点
}
else if (!p->m_lChild && !p->m_rChild)//左右孩子都不存在
{
PNode t = p;
p = nullptr;
delete t;
return true;
}
else
{
PNode t = p;
p = (p->m_lChild == nullptr) ? p->m_rChild : p->m_lChild;
delete t;
return true;
}
}
else if (key < p->m_key)
return Delete(key, p->m_lChild);
else
return Delete(key, p->m_rChild);
}
}
/* 查找 */
bool Find(int key, PNode & p)
{
if (p == nullptr)
return false;
else
{
if (key == p->m_key)
return true;
else if (key < p->m_key)
return Find(key, p->m_lChild);
else
return Find(key, p->m_rChild);
}
}
/* 求以该节点为树根的树的高度 */
int Height(PNode & p)
{
if (p == nullptr)
return 0;
else
return max(Height(p->m_lChild), Height(p->m_rChild)) + 1;
}
/* 层次遍历 */
void PrintTheLevel(PNode & p, int level)
{
if (!p || level <= 0)
return;
if (level == 1)
{
cout << p->m_key << " ";
return;
}
PrintTheLevel(p->m_lChild, level - 1);
PrintTheLevel(p->m_rChild, level - 1);
}
void LevelOrder(PNode & p)
{
int depth = Height(p);
for (int i = 1; i <= depth; i++)
{
PrintTheLevel(p, i);
cout << endl;
}
cout << endl;
}
int main()
{
Add(45, root);
Add(12, root);
Add(53, root);
Add(3, root); Add(3, root);
Add(37, root);
Add(100, root);
Add(24, root);
Add(61, root);
Add(90, root); Add(90, root);
Add(78, root);
LevelOrder(root);
Delete(45, root);
Delete(61, root);
LevelOrder(root);
return 0;
}
四:数据测试
返回目录---->数据结构与算法目录