二叉排序树类的: C++ 实现
#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++ 实现的更多相关文章
- 二叉排序树详解——PHP代码实现
二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树. 一.定义 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: 若左子树不空 ...
- Python 树表查找_千树万树梨花开,忽如一夜春风来(二叉排序树、平衡二叉树)
什么是树表查询? 借助具有特殊性质的树数据结构进行关键字查找. 本文所涉及到的特殊结构性质的树包括: 二叉排序树. 平衡二叉树. 使用上述树结构存储数据时,因其本身对结点之间的关系以及顺序有特殊要求, ...
- Java类的继承与多态特性-入门笔记
相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...
- 数据结构-用C++实现一个二叉树,递归方法中序遍历
1:二叉排序树,又称二叉树.其定义为:二叉排序树或者空树,或者是满足如下性质的二叉树. (1)若它的左子树非空,则左子树上所有节点的值均小于根节点的值. (2)若它的右子树非空,则右子树上所有节点的值 ...
- 二叉排序树(BST)创建,删除,查找操作
binary search tree,中文翻译为二叉搜索树.二叉查找树或者二叉排序树.简称为BST 一:二叉搜索树的定义 他的定义与树的定义是类似的,也是一个递归的定义: 1.要么是一棵空树 2.如果 ...
- 数据结构图文解析之:树的简介及二叉排序树C++模板实现.
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- Java二叉排序树(转)
一.二叉排序树定义 1.二叉排序树的定义 二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree).其定义为:二叉排序树或者是空树,或者是满足如下性 ...
- 在Visual Studio中使用Debug Visualizers在C++中实现对原始类的自定义调试信息显示
在Visual Studio中使用Debug Visualizers在C++中实现对原始类的自定义调试信息显示 当我们在VS的C++中使用vector.list.map等这些STL容器,在开启调试的时 ...
- Android版数据结构与算法(八):二叉排序树
本文目录 前两篇文章我们学习了一些树的基本概念以及常用操作,本篇我们了解一下二叉树的一种特殊形式:二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree) ...
随机推荐
- MATLAB的两种移位运算
MATLAB的两种移位运算: 1)circshift矩阵移位 circshift:循环移位数组 语法:B = circshift(A,shiftize) 说明: B = circshift(A,sh ...
- java 文件字节和字符流 缓冲流
流的原理 1) 在 Java 程序中,对于数据的输入/输出操作以“流”(stream) 方式进行:2) J2SDK 提供了各种各样的“流”类,用以获取不同种类的数据:程序中通过标准的方法输入或输出数据 ...
- LeetCode202:Happy Number 。C#版,在vs2010中通过,leetcode中Wrong Answer
static List<int> nums = new List<int>(); public static bool IsHappy(int n) { int newint ...
- 没有内涵段子可以刷了,利用Python爬取段友之家贴吧图片和小视频(含源码)
由于最新的视频整顿风波,内涵段子APP被迫关闭,广大段友无家可归,但是最近发现了一个"段友"的app,版本更新也挺快,正在号召广大段友回家,如下图,有兴趣的可以下载看看(ps:我不 ...
- IIS导入.pfx证书时报错:"A specified logon session does not exist. It may already have been terminated."
在IIS中可以直接导入.pfx文件来给站点绑定https协议: 如果在导入.pfx文件时,不选择"Allow this certificate to be exported"的话 ...
- linux编程之信号量
一.概念 linux信号量: 允许多个线程同时进入临界区,可以用于进程间的同步. 和互斥锁(mutex)的区别: 互斥锁只允许一个线程进入临界区. 所在头文件: semaphore.h 二.主要函数 ...
- Jenkins 配置 Node.js 项目
开始 弄清楚 Jenkins 服务器 用 Jenkins 管理员账号下载 NodeJS Plugin 系统管理 ---> 全局工具配置 ---> NodeJS ---> 安装 --- ...
- [python][spark]wholeTextFiles 读入多个文件的例子
$pwd /home/training/mydir $cat file1.json {"firstName":"Fred", "lastName&qu ...
- [HAOI2017]供给侧改革[离线、trie]
题意 题目链接 分析 由于数据随机所以 LCP 不会很长,维护每个位置后 40 个字符构成的01串. 将询问离线维护,以当前右端点为 R 的每个长度的 LCP 的第一个出现位置 f(这个信息显然是单调 ...
- python之魔法方法介绍
1.1. 简介 什么是魔法方法呢?它们在面向对象的Python的处处皆是.它们是一些可以让你对类添加“魔法”的特殊方法. 它们经常是两个下划线包围来命名的(比如 __init__ , __lt__ ) ...