#include<iostream>
using namespace std; template<class T>
struct TreeNode
{
T element;
TreeNode<T>*parent, *lnode, *rnode;
TreeNode(){ parent = lnode = rnode = NULL; }
TreeNode(const T& key)
{
element = key;
parent = lnode = rnode = NULL;
}
}; template<class T>
class BStree
{
public:
BStree() :root(NULL){}
//获取根结点
TreeNode<T>* Getroot(){ return root; }
//中序遍历
void Inorder(TreeNode<T>*node);
//递归查找
TreeNode<T>* TreeSearch(TreeNode<T>*node, T key);
//迭代查找
TreeNode<T>* IterativeTreeSearch(TreeNode<T>*node, T key);
//插入元素
void TreeInsert(T key);
//最大值
TreeNode<T>*TreeMax(TreeNode<T>*node);
//最小值
TreeNode<T>*TreeMin(TreeNode<T>*node);
//查找前驱结点
TreeNode<T>*TreePredecessor(T key);
//查找后继结点
TreeNode<T>*TreeSuccessor(T key);
//用结点 nodeM 替换结点 nodeN,删除操作的辅助函数
void TransPlant(TreeNode<T>*nodeM, TreeNode<T>*nodeN);
//删除结点是key的元素
void Delete(T key); private:
TreeNode<T>* root;
}; //中序遍历
template<class T>
void BStree<T>::Inorder(TreeNode<T>*node)
{
if (node == NULL)
return;
else
{
Inorder(node->lnode);
cout << node->element << " ";
Inorder(node->rnode);
}
} //递归查找,调用时,node的初始值是root
template<class T>
TreeNode<T>* BStree<T>::TreeSearch(TreeNode<T>*node, T key)
{
if ((node == NULL) || (key == node->element))
{
if (node == NULL)
cout << "不存在该元素" << endl;
else
cout << "存在该元素" << endl;
return node;
} if (key > node->element)
return TreeSearch(node->rnode,key);
else
return TreeSearch(node->lnode,key);
} //迭代查找,node参数为root(根结点)
template<class T>
TreeNode<T>* BStree<T>::IterativeTreeSearch(TreeNode<T>*node, T key)
{
while (node != NULL&&key != node->element)
{
if (key < node->element)
node = node->lnode;
else
node = node->rnode;
}
if (node == NULL)
cout << "不存在该元素" << endl;
else
cout << "存在该元素" << endl;
return node;
} //插入元素
template<class T>
void BStree<T>::TreeInsert(T key)
{
TreeNode<T>* y = NULL;
TreeNode<T>* x = root;
TreeNode<T>* z = new TreeNode<T>(key); //将需要插入的元素放入新建立的结点中
while (x != NULL) //找到要插入位置的双亲结点
{
y = x;
if (z->element < x->element)
x = x->lnode;
else
x = x->rnode;
}
z->parent = y;
if (y == NULL) // 判断要插入的是:左 或 右结点
root = z;
else if (z->element>y->element)
y->rnode = z;
else
y->lnode = z;
} //最大值,一直遍历所给结点的右子树
template<class T>
TreeNode<T>*BStree<T>::TreeMax(TreeNode<T>*node)
{
while (node->rnode != NULL)
node = node->rnode;
cout << "最大值是:" << node->element << endl;
return node;
} // 最小值,一直遍历所给结点的左子树
template<class T>
TreeNode<T>*BStree<T>::TreeMin(TreeNode<T>*node)
{
while (node->lnode != NULL)
node = node->lnode;
cout << "最小值是:" << node->element << endl;
return node;
} //查找后继结点
template<class T>
TreeNode<T>*BStree<T>::TreeSuccessor(T key)
{
TreeNode<T>* x = TreeSearch(root, key); //查找关键字key所对应的结点
if (x->rnode != NULL) //如果结点x存在右结点,则直接查找右结点为跟的最小值
return TreeMin(x->rnode);
/*若,不存在右结点
1、if(x==x->parent->lnode), 则 x 的后继元素即是 x 的双亲结点
2、if(x==x->parent->rnode),则 x 的双亲 y 及 y->lnode均小于x,
直到 x 的某一祖先 Yn 为左节点时,Yn 的双亲即是 x 的后继元素
*/
TreeNode<T>*y = x->parent;
while (y != NULL&&x == y->rnode)
{
x = y;
y = y->parent;
}
return y;
} //查找前驱结点
template<class T>
TreeNode<T>*BStree<T>::TreePredecessor(T key)
{
TreeNode<T>* x = TreeSearch(root, key); //查找关键字key所对应的结点
if (x->lnode != NULL)
return TreeMax(x->lnode); //若x的左子树不为空,查找左子树的最大值
TreeNode<T>*y = x->parent;
while (y != NULL&&x == y->lnode)
{
x = y;
y = y->lnode;
}
return y;
} //用结点 m 替换结点 n,不包括v的左右子树的更新
template<class T>
void BStree<T>::TransPlant(TreeNode<T>*nodeM, TreeNode<T>*nodeN)
{
if (nodeN->parent == NULL)
root = nodeM;
else if (nodeN == nodeN->parent->lnode) // nodeN 是左结点,更新nodeN->parent 的左结点
nodeN->parent->lnode = nodeM;
else
nodeN->parent->rnode = nodeM;
if (nodeM != NULL)
nodeM->parent = nodeN->parent;
} //删除结点关节字是key的元素
template<class T>
void BStree<T>::Delete(T key)
{
TreeNode<T>*z = IterativeTreeSearch(root,key); //z 是要删除的结点
if (z->lnode == NULL)
TransPlant(z->rnode,z);
else if (z->rnode == NULL)
TransPlant(z->lnode,z);
else
{
//找要删除结点的后继元素,
TreeNode<T>*y = TreeMin(z->rnode); //类的成员函数在调用成员函数(模板)时,直接写函数名,不需要<T>
if (y->parent != z)
{
TransPlant(y->rnode, y); //用 y 的右结点替代 y
y->rnode = z->rnode; //y的右结点 = z的右结点
y->rnode->parent = y;
}
TransPlant(y,z); //用 y替代z
y->lnode = z->lnode;
y->lnode->parent = y;
}
}
#include<iostream>
#include"stdlib.h"
#include<time.h>
#include"BSTreecpp.cpp"
using namespace std; int main()
{
//生成要插入的数据
int max = ;
int min = ;
srand((unsigned)time(NULL));
int a[] = {};
int x = ;
for (int i = ; i < ; i++)
{
a[i] = rand() % (max - min) + min;
cout << a[i] << " ";
}
cout << "输入数据:" << endl;
BStree<int>myTree;
for (int i = ; i < ; i++)
myTree.TreeInsert(a[i]);
myTree.Inorder(myTree.Getroot());
cout << "二叉搜索树中序遍历:" << endl;
//验证递归查找
int b = ;
TreeNode<int>* A = myTree.TreeSearch(myTree.Getroot(), b);
//验证迭代查找
TreeNode<int>* B = myTree.IterativeTreeSearch(myTree.Getroot(), a[]);
//验证求取最大值
TreeNode<int>* C = myTree.TreeMax(myTree.Getroot());
//验证求取最小值
TreeNode<int>* D = myTree.TreeMin(myTree.Getroot());
//求取后继结点
TreeNode<int>*E = myTree.TreeSuccessor(a[]);
cout << a[] << " 的后继元素是:" << E->element << endl;
//求取前驱结点
TreeNode<int>*F = myTree.TreePredecessor(a[]);
cout << a[] << " 的前驱元素是:" << F->element << endl;
//验证删除结点
myTree.Delete(a[]);
myTree.Inorder(myTree.Getroot());
cout << "二叉搜索树删除元素后:" << endl;
system("pause");
return ;
}

二叉排序树类的: C++ 实现的更多相关文章

  1. 二叉排序树详解——PHP代码实现

    二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树. 一.定义 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: 若左子树不空 ...

  2. Python 树表查找_千树万树梨花开,忽如一夜春风来(二叉排序树、平衡二叉树)

    什么是树表查询? 借助具有特殊性质的树数据结构进行关键字查找. 本文所涉及到的特殊结构性质的树包括: 二叉排序树. 平衡二叉树. 使用上述树结构存储数据时,因其本身对结点之间的关系以及顺序有特殊要求, ...

  3. Java类的继承与多态特性-入门笔记

    相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...

  4. 数据结构-用C++实现一个二叉树,递归方法中序遍历

    1:二叉排序树,又称二叉树.其定义为:二叉排序树或者空树,或者是满足如下性质的二叉树. (1)若它的左子树非空,则左子树上所有节点的值均小于根节点的值. (2)若它的右子树非空,则右子树上所有节点的值 ...

  5. 二叉排序树(BST)创建,删除,查找操作

    binary search tree,中文翻译为二叉搜索树.二叉查找树或者二叉排序树.简称为BST 一:二叉搜索树的定义 他的定义与树的定义是类似的,也是一个递归的定义: 1.要么是一棵空树 2.如果 ...

  6. 数据结构图文解析之:树的简介及二叉排序树C++模板实现.

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  7. Java二叉排序树(转)

    一.二叉排序树定义 1.二叉排序树的定义 二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree).其定义为:二叉排序树或者是空树,或者是满足如下性 ...

  8. 在Visual Studio中使用Debug Visualizers在C++中实现对原始类的自定义调试信息显示

    在Visual Studio中使用Debug Visualizers在C++中实现对原始类的自定义调试信息显示 当我们在VS的C++中使用vector.list.map等这些STL容器,在开启调试的时 ...

  9. Android版数据结构与算法(八):二叉排序树

    本文目录 前两篇文章我们学习了一些树的基本概念以及常用操作,本篇我们了解一下二叉树的一种特殊形式:二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree) ...

随机推荐

  1. Java基础之集合篇(模块记忆、精要分析)

    千里之行,始于足下.把别人的变成自己,再把自己的分享给别人,这也是一次提升的过程.本文的目的是以一篇文章从整体把握集合体系又不失一些细节上的实现,高手路过. 集合的作用与特点 Java是一门面向对象语 ...

  2. Struts 2.5.20 在Eclipse IDE中的配置和开发实例

    零.参考博客1.Struts框架入门教程2.Struts 2.5.10.1配置 3.eclipse中搭建Struts2.5.16 4.Struts2.5+eclipse+tomcat8.5配置 注意: ...

  3. Linux DNS原理简介及配置

    Linux DNS原理简介及配置 DNS简介 DNS原理 域名解析的过程 资源记录 DNS BIND安装配置 一.简介 一般来讲域名比IP地址更加的有含义.也更容易记住,所以通常用户更习惯输入域名来访 ...

  4. angularjs自定义指令Directive

    今天学习angularjs自定义指令Directive.Directive是一个非常棒的功能.可以实现我们自义的的功能方法. 下面的例子是演示用户在文本框输入的帐号是否为管理员的帐号"Adm ...

  5. 使用第三方库(Senparc)完成小程序支付 - z

    https://www.cnblogs.com/zmaiwxl/p/8931585.html

  6. Java获取指定包名下的所有类的全类名的解决方案

        最近有个需求需要获取一个指定包下的所有类的全类名,因此特意写了个获取指定包下所有类的全类名的工具类.在此记录一下,方便后续查阅 一.思路         通过ClassLoader来查找指定包 ...

  7. JDK1.7 HashMap 导致循环链表

    转载自:疫苗:JAVA HASHMAP的死循环 在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race C ...

  8. Nginx SSL+tomcat集群,request.getScheme() 取到https正确的协议

    最近在做一个项目, 架构上使用了 Nginx +tomcat 集群, 且nginx下配置了SSL,tomcat no SSL,项目使用https协议 但是,明明是https url请求,发现 log里 ...

  9. Ionic 入门与实战之第一章:Ionic 介绍与相关学习资源

    原文发表于我的技术博客 本文是「Ionic 入门与实战」系列连载的第一章,主要对 Ionic 的概念.发展历程.适配的移动平台等知识进行了介绍,并分享了 Ionic 相关的学习资源. 原文发表于我的技 ...

  10. ZooKeeper 典型的应用场景——及编程实现

    如何使用 Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储,但是 Zookeeper 并不是用来专门存储 ...