#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. go标准库的学习-time

    参考https://studygolang.com/pkgdoc 导入形式: import "time" time包提供了时间的显示和测量用的函数.日历的计算采用的是公历. 1&g ...

  2. 使用scrapy爬取海外网学习频道

    一:创建项目文件 1:首先在终端使用命令scrapy startproject huaerjieribao 创建项目 2:创建spider 首先cd进去刚刚创建的项目文件overseas 然后执行ge ...

  3. Android学习之基础知识九 — 数据存储(持久化技术)之使用LitePal操作数据库

    上一节学习了使用SQLiteDatabase来操作SQLite数据库的方法,接下来我们开始接触第一个开源库:LitePal.LitePal是一款开源的Android数据库框架,它采用了对象关系映射(O ...

  4. 1-微信小程序开发(安装软件和运行第一个微信小程序)

    https://developers.weixin.qq.com/miniprogram/dev/ 我的 打开 上传成功后

  5. 9-(基础入门篇)云端安装MQTT服务器

    https://www.cnblogs.com/yangfengwu/p/9953703.html 记得把文件拷贝到上一节配置的和云端共享的那个盘里面,好拷贝文件到云服务器 进入到bin目录 咱先以控 ...

  6. 使用Windows API进行串口编程

    使用Windows API进行串口编程   串口通信一般分为四大步:打开串口->配置串口->读写串口->关闭串口,还可以在串口上监听读写等事件.1.打开和关闭串口Windows中串口 ...

  7. HNOI2019 爆零记

    HNOI2019爆零记 day \(-inf\) ~ day \(0\) 开学一周之后才停的课,停课之后就开始每天被包菜.我三月份几乎没有更博,就是因为每天都被虐的自闭了. day \(0\) 本来是 ...

  8. 欧拉函数(小于或等于n的数中与n互质的数的数目)&& 欧拉函数线性筛法

    [欧拉函数] 在数论,对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目.此函数以其首名研究者欧拉命名,它又称为Euler’s totient function.φ函数.欧拉商数等. 例如φ( ...

  9. [UWP 自定义控件]了解模板化控件(2):模仿ContentControl

    ContentControl是最简单的TemplatedControl,而且它在UWP出场频率很高.ContentControl和Panel是VisualTree的基础,可以说几乎所有VisualTr ...

  10. ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-WebApi与Unity注入

    系列目录 前言: 有时候我们系统需要开放数据给手机App端或其他移动设备,不得不说Asp.net WebApi是目前首选 本节记录Asp.net MVC WebApi怎么利用Unity注入.系列开头已 ...