#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. python3打包成exe---pyinstaller方法

    前言: 主要介绍python3的pyinstaller打包方法 pyinstaller安装参考地址:http://www.pyinstaller.org/ pywin32的下载地址:https://s ...

  2. C++基类的析构函数定义为虚函数的原因

    1:每个析构函数只会清理自己的成员(成员函数前没有virtual).2:可能是基类的指针指向派生类的对象,当析构一个指向派生类的成员的基类指针,这时程序不知道这么办,可能会造成内存的泄露,因此此时基类 ...

  3. Luogu P1525 关押罪犯

    传送门 首先 这是一个并查集= = 这道题其实明白了还挺简单的qwq 思路: 因为只看仇恨值最大的一对儿,所以把他们从大到小排序,越大的就尽量分开,直到不能再分为止qwq q[x]表示x最大的敌人(x ...

  4. Tensorflow-hub[例子解析2]

    接Tensorflow-hub[例子解析1]. 3 基于文本词向量的例子 3.1 创建Module 可以从Tensorflow-hub[例子解析1].中看出,hub相对之前减少了更多的工作量. 首先, ...

  5. CF939D Love Rescue 并查集

    传送门 题意:给出两个由小写字母构成的长度相等的字符串$S$与$T$,给出变换$c1\,c2$表示将两个字符串中所有$c1$字符变为$c2$,求将$S$和$T$通过这种变换变为相等字符串的最少变换次数 ...

  6. Luogu P3398 仓鼠找sugar

    这还是一道比较好的树剖题(去你的树剖,LCA即可) 这里主要讲两种思路,其实都是很基本也很经典的 1 树链剖分 还是先讲一下这种算法吧,虽然写起来很烦(不过感觉写多了就习惯了,而且还有一种莫名的快感) ...

  7. [Oracle]数据库的Control File 取Dump后的样例

    [Oracle]数据库的Control File 取Dump后的样例: 片段截取-------------------------------(size = 40, compat size = 40, ...

  8. DefWindowProc是一个会产生消息的函数

    先看一道题目: 当用户点击右上角关闭按钮的时候,请给下列Windows做出的响应排个序:A:发送 WM_QUIT 消息     B:发送 WM_CLOSE 消息     C:发送 WM_DESTROY ...

  9. 【持续更新中···】Linux下的小技巧

    1.Linux回到上级文件的命令: cd ..回到上一级目录(注意:cd 和..中间有空格) cd ~回到home目录 cd -回到某一目录

  10. GNU构建系统和AutoTools

    注:本篇博客是阅读文末[参考博客]的讲解所写,内容非原创,仅是学习笔记 1. 概述2. 不同视角的程序构建2.1 用户视角2.2 开发者视角3. 导图图片4. configure选项参考博客 1. 概 ...