二叉排序树详解及实现
- 1.什么是二叉排序树
- 2.二叉排序树的数据结构
- 2.1二叉排序树的节点类型
- 2.2二叉排序树中插入某个元素
- 2.3 二叉排序树中按值查找元素
- 2.4 找排序二叉树中的最小值
- 2.5返回排序二叉树中ptr中序遍历的后续节点
- 2.6 寻找排序二叉树中的最大值
- 2.7 寻找二叉树中中序遍历ptr节点的前驱
- 2.8中序遍历排序二叉树(从小到大打印排序二叉树所有元素)
- 2.9 逆向打印排序二叉树(从大到小打印排序二叉树所有元素)
- 2.10删除排序二叉树的结点元素为value的结点
- 3.具体程序及运行结果
1.什么是二叉排序树
二叉排序树(Binary Sorting Tree)又称二叉搜索树(Binary Search Tree),是一种特殊结构的二叉数,作为一种排序和查找的手段,对应有序表的对半查找,通常亦被称为数表。其定义也是递归的。
二叉排序树的定义:
每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同;
二叉排序树或者是空树或者是具有下述性质的二叉数,
①其左子树上所有结点的数据值均小于根结点的数据值;
②右子树上所有结点的数据值均大于根结点的数据值;
③左子树和右子树又各是一棵二叉排序树。
二叉排序树用中序遍历就可以得到由小到大的有序序列
2.二叉排序树的数据结构
2.1二叉排序树的节点类型
typedef struct BstNode
{
KeyType key;
BstNode* parent;
BstNode* leftchild;
BstNode* rightchild;
}BstNode;
2.2二叉排序树中插入某个元素
bool Binary_Sort_Tree::Insert_Value(KeyType value)
{
if (root ==nullptr)
{
root = MakeNode(value);
return true;
}
BstNode* ptr = root;
BstNode* parent = NULL;
while (ptr != NULL && ptr->key != value)
{
parent = ptr;
ptr = value > ptr->key ? ptr->rightchild : ptr->leftchild;
}
if (ptr != NULL && ptr->key == value) return false;
ptr = MakeNode(value);
ptr->parent = parent;
if (ptr->key > parent->key) { parent->rightchild = ptr; }
else { parent->leftchild = ptr; }
cursize++;
return true;
}
2.3 二叉排序树中按值查找元素
如果要查找的元素值>根节点值,就在根节点右边查找,否则在根节点左边查找。
BstNode* Binary_Sort_Tree::FindValue(KeyType value)
{
BstNode* ptr = root;
while (ptr != nullptr && ptr->key != value)
{
ptr = value > ptr->key ? ptr->rightchild : ptr->leftchild;
}
return ptr;
}
2.4 找排序二叉树中的最小值
根据排序二叉树的性质,可以很轻松的得到最小值即为最左边节点的值。
BstNode* Binary_Sort_Tree::FirstNodeByMiddleOrder()
{
BstNode* ptr = root;
while (ptr && ptr->leftchild)
{
ptr = ptr->leftchild;
}
return ptr;
}
2.5返回排序二叉树中ptr中序遍历的后续节点
节点ptr的后续节点为排序二叉树中第一个比ptr->key大的元素,即可以分为如下两种情况:
①如果ptr存在右子树,则ptr的后续节点为ptr右子树的最左端的节点。
②如果ptr不存在右子树,则ptr的后续节点可以回溯到根节点
具体如下:
BstNode* Binary_Sort_Tree::NextNodeByMiddleOrder(BstNode* ptr)
{
if (ptr == NULL) return ptr;
if (ptr->rightchild != NULL)
{
return FirstNodeByMiddleOrder(ptr->rightchild);
}
else
{
BstNode* parent = ptr->parent;
while (parent != NULL && parent->leftchild != ptr)
{
ptr = parent;
parent = ptr->parent;
}
return parent;
}
}
2.6 寻找排序二叉树中的最大值
根据排序二叉树的性质,可以很轻松的得到最小值即为最右边节点的值。
BstNode* Binary_Sort_Tree::LastNodeByMiddleOrder()
{
BstNode* ptr = root;
while (ptr && ptr->rightchild)
{
ptr = ptr->rightchild;
}
return ptr;
}
2.7 寻找二叉树中中序遍历ptr节点的前驱
节点ptr的前驱为排序二叉树中第一个比ptr->key小的元素,即可以分为如下两种情况:
①如果ptr存在左子树,则ptr的后续节点为ptr左子树。
②如果ptr不存在左子树,则ptr的后续节点可以回溯到根节点
具体如下:
BstNode* Binary_Sort_Tree::PrecursorofPtr(BstNode* ptr)
{
if (ptr == NULL) return ptr;
if (ptr->leftchild != NULL)
{
return LastNodeByMiddleOrder(ptr->leftchild);
}
else
{
BstNode* parent = ptr->parent;
while (parent != NULL && parent->rightchild != ptr)
{
ptr = parent;
parent = ptr->parent;
}
return parent;
}
}
2.8中序遍历排序二叉树(从小到大打印排序二叉树所有元素)
void Binary_Sort_Tree::MiddleOrder()
{
cout << "排序二叉树的非递归中序遍历:" << endl;
BstNode* ptr = FirstNodeByMiddleOrder();
for (; ptr != nullptr; ptr = NextNodeByMiddleOrder(ptr))
{
cout << ptr->key << " ";
}
cout << endl;
}
2.9 逆向打印排序二叉树(从大到小打印排序二叉树所有元素)
void Binary_Sort_Tree::ReverseInorder()
{
BstNode* ptr = root;
cout << "二叉排序树的逆向打印:" << endl;
for (BstNode* p = LastNodeByMiddleOrder(ptr); p != NULL; p = PrecursorofPtr(p))
{
cout << p->key << " ";
}
cout << endl;
}
2.10删除排序二叉树的结点元素为value的结点
删除某个元素可分为以下三种情况:
①如果是叶子节点直接删除即可。
②如果不是叶子节点具体讨论如下:
bool Binary_Sort_Tree::RemoveNode(KeyType value)
{
BstNode* ptr = root;
if (ptr == NULL) return false;
BstNode* pa = NULL;
BstNode* p = ptr;
while (p && p->key != value)
{
p = value < p->key ? p->leftchild : p->rightchild;
}
if (p == NULL) return false;
if (p->leftchild && p->rightchild)
{
BstNode* q = FirstNodeByMiddleOrder(p->rightchild);
p->key = q->key;
p = q;
}
pa = p->parent;
BstNode* child = p->leftchild != NULL ? p->leftchild : p->rightchild;
if (child)
{
child->parent = pa;
}
if (pa == NULL)
{
ptr = child;
}
else
{
if (pa->leftchild == p)
{
pa->leftchild = child;
}
else
{
pa->rightchild = child;
}
}
cursize--;
delete p;
return true;
}
3.具体程序及运行结果
程序如下:
二叉排序树的代码下载
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)