二叉查找树(BinarySearch Tree,也叫二叉搜索树,或称二叉排序树BinarySort Tree)或者是一棵空树,或者是具有下列性质的二叉树:

(1)若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值;

(2)若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值;

(3)它的左、右子树也分别为二叉查找树。

下面是它的几个重要函数:

插入结点:

【思路1】递归

终止条件(1,2):

1.若插入到一个空树中,则新建结点为根结点,左右孩子置为空,返回true

2.若等于根结点的值,返回false

3.若当前值小于根结点的值,递归左子树,否则递归右子树

 template<class T>
bool BinarySearchTree<T>::InsertNode(BinaryTreeNode<T> * &root, T newpointer)
{
if (root == NULL)
{
root = new BinaryTreeNode<T>;
root->element = newpointer;
root->LeftChild = root->RightChild = NULL;
return true;
}
if (newpointer == root->element)
return false;
if (newpointer < root->element)
return InsertNode(root->LeftChild, newpointer);
else
return InsertNode(root->RightChild, newpointer);
}

【思路2】非递归

1.若二叉树为空,则首先单独生成根结点

2.执行查找算法,找出被插结点的父亲结点

3.判断被插结点是其父亲结点的左、右儿子,并将被插结点作为叶子结点插入

注:新插入的结点总是叶子结点

 template<class T>
bool BinarySearchTree<T>::InsertNode(BinaryTreeNode<T> * &root, T newpointer)
{
if (root == NULL)
{
root = new BinaryTreeNode<T>;
root->element = newpointer;
root->LeftChild = root->RightChild = NULL;
return true;
}
BinaryTreeNode<T> *pointer = root;
while(pointer != NULL)
{
if (newpointer == pointer->element)
return false;
else if (newpointer < pointer->element)
{
if(pointer->LeftChild == NULL)
{
BinaryTreeNode<T>* l = new BinaryTreeNode<T>(newpointer);
l->LeftChild = l->RightChild = NULL;
pointer->LeftChild = l;
return true;
}
pointer = pointer->LeftChild;
}
else
{
if(pointer->RightChild == NULL)
{
BinaryTreeNode<T>* r = new BinaryTreeNode<T>(newpointer);
r->LeftChild = r->RightChild = NULL;
pointer->RightChild = r;
return true;
}
pointer = pointer->RightChild;
}
}
}

删除结点:

【思路】删除二叉搜索树中结点要根据删除的位置分情况讨论

1.删除叶子结点

操作:直接删除,更改它的父亲结点的相应指针场为空。

2.删除结点只有左儿子或只有右儿子

操作:将该结点的子树直接接到该结点位置

3.删除结点有两个子结点

(1)合并删除

(2)通过复制进行删除

选取替身(左子树中最大的结点或右子树中最小的结点)替换到删除结点的位置

 template<class T>
void BinarySearchTree<T>::deleteBinarySearchTree(BinaryTreeNode<T>* root, T x)
{
bool find = false;
int flag = ;//标志要删除的结点是前驱结点pre的左孩子还是右孩子
BinaryTreeNode<T> *pre = NULL;
while (root && !find)
{
if (x == root->element)
{
find = true;
}
else if (x < root->element)
{
pre = root;
root = root->LeftChild;
flag = -;
}
else
{
pre = root;
root = root->RightChild;
flag = ;
}
}
if (root == NULL)
{
cout << "未找到要删除元素" << endl;
return;
}
//此时root为要删除结点 //要删除结点是叶子结点
if (root->isLeaf())
{
if (flag == )
{
delete root;
root = NULL;
}
else if (flag == -)
{
pre->LeftChild = NULL;
delete root;
root = NULL;
}
else
{
pre->RightChild = NULL;
delete root;
root = NULL;
}
} //要删除结点具有左右子结点
else if (root->LeftChild && root->RightChild)
{
//复制删除,选取左子树中最大的结点替换
BinaryTreeNode<T> *t = root;
BinaryTreeNode<T> *s = root->LeftChild;
while (s->RightChild)
{
t = s;
s = s->RightChild;
}
root->element = s->element; //此时S只有左孩子,需要连接到它的前驱结点t上
if (root == t)//while循环未执行
{
t->LeftChild = s->LeftChild;
}
else//while循环已执行
{
t->RightChild = s->LeftChild;
}
delete s;
s = NULL;
} else//要删除结点为单支子树根结点
{
if (flag == )//root为根结点
{
if (root->LeftChild)
{
pre = root;
root = root->LeftChild;
delete pre;
pre = NULL;
}
else
{
pre = root;
root = root->RightChild;
delete pre;
pre = NULL;
}
}
else if (flag == -)//root为pre的左子树
{
if (root->LeftChild)//要删除结点只存在左子树
{
pre->LeftChild = root->LeftChild;
delete root;
root = NULL;
}
else//要删除结点只存在右子树
{
pre->LeftChild = root->RightChild;
delete root;
root = NULL;
}
}
else//root为pre的右子树
{
if (root->LeftChild)//要删除结点只存在左子树
{
pre->RightChild = root->LeftChild;
delete root;
root = NULL;
}
else//要删除结点只存在右子树
{
pre->RightChild = root->RightChild;
delete root;
root = NULL;
}
}
}
}

查找结点:

【思路】分割式查找法:

1.若根结点的关键码等于查找的关键码,成功。

2.否则,若小于根结点的关键码,查其左子树;大于根结点的关键码,查其右子树。

二叉搜索树的高效率在于继续检索时只需查找两棵子树之一。

 template<class T>
BinaryTreeNode<T>* BinarySearchTree<T>::Search(BinaryTreeNode<T>* root, T x)
{
BinaryTreeNode<T>* current = root;
while((NULL != current) && (x != current->element))
{
if(x < current->element)
current = Search(root->LeftChild,x);
else
current = Search(root->RightChild,x);
}
return current;
}

[BinaryTree] 二叉搜索树(二叉查找树、二叉排序树)的更多相关文章

  1. 《数据结构与算法分析——C语言描述》ADT实现(NO.03) : 二叉搜索树/二叉查找树(Binary Search Tree)

    二叉搜索树(Binary Search Tree),又名二叉查找树.二叉排序树,是一种简单的二叉树.它的特点是每一个结点的左(右)子树各结点的元素一定小于(大于)该结点的元素.将该树用于查找时,由于二 ...

  2. 判断一棵树是否为二叉搜索树(二叉排序树) python

    输入一棵树,判断这棵树是否为二叉搜索树.首先要知道什么是排序二叉树,二叉排序树是这样定义的,二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的 ...

  3. 二叉搜索树 & 二叉树 & 遍历方法

    二叉搜索树 & 二叉树 & 遍历方法 二叉搜索树 BST / binary search tree https://en.wikipedia.org/wiki/Binary_searc ...

  4. 【Java】 大话数据结构(11) 查找算法(2)(二叉排序树/二叉搜索树)

    本文根据<大话数据结构>一书,实现了Java版的二叉排序树/二叉搜索树. 二叉排序树介绍 在上篇博客中,顺序表的插入和删除效率还可以,但查找效率很低:而有序线性表中,可以使用折半.插值.斐 ...

  5. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  6. OBST(Optimal Binary Tree最优二叉搜索树)

    二叉搜索树 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的 ...

  7. &12 二叉搜索树

    #1,定义 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的 ...

  8. 《剑指offer》— JavaScript(23)二叉搜索树的后序遍历序列

    二叉搜索树的后序遍历序列 题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 相关知识 二叉查找树(B ...

  9. 剑指Offer——二叉搜索树的后序遍历序列

    题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 分析: 二叉查找树(Binary Search ...

随机推荐

  1. 【TOJ 1449】Area of Circles II(求不同位置的两圆面积之和)

    描述 There are two circles on the plane. Now you must to calculate the area which they cover the plane ...

  2. ABAP术语-Document Number

    Document Number 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/28/1055636.html Key which ident ...

  3. layDate 闪现 循环一个以上会闪现

    一个render一次渲染一个日期组件,这个是内置的,所以需要循环绑定, 又不能确定页面有多少个,还好layDate 提供了内置方法, //同时绑定多个 lay('.test-item').each(f ...

  4. 使用Cygwin在WIN系统下处理文本常用命令

    1.打开Cygwin,把需要处理的文本复制你的安装目录例如:D:\cygwin\home\Administrator 使用 ls命令查看根目录文件 2.现在我们就可以对1.txt文本进行操作, 3.我 ...

  5. Linux系统定时任务crond那些事

    1 Linux系统定时任务 1.1 定时任务介绍 1.1.1 Crond是什么? Crond是linux系统中用来定期执行命令或指定程序任务的一种服务或软件.Centos5/ linux系统安装完操作 ...

  6. PHP基础 (麦子学院 第二阶段)

    zendstudio 10.0破解版,新建完项目后,首先修改项目的编码方式,统一改成utf-8 (选中项目,再右键properties:Text file encoding).修改字体大小. apac ...

  7. python+matplotlib 绘制等高线

    python+matplotlib 绘制等高线 步骤有七: 有一个m*n维的矩阵(data),其元素的值代表高度 构造两个向量:x(1*n)和y(1*m).这两个向量用来构造网格坐标矩阵(网格坐标矩阵 ...

  8. mysql 5.8 查询最新一条数据

    SELECT * FROM ( ,) FROM (SELECT * FROM or_task_node ORDER BY created_date DESC) temp ) AS vars ) t g ...

  9. (数据科学学习手札15)DBSCAN密度聚类法原理简介&Python与R的实现

    DBSCAN算法是一种很典型的密度聚类法,它与K-means等只能对凸样本集进行聚类的算法不同,它也可以处理非凸集. 关于DBSCAN算法的原理,笔者觉得下面这篇写的甚是清楚练达,推荐大家阅读: ht ...

  10. 动态规划(DP)算法

    参考https://blog.csdn.net/libosbo/article/details/80038549 动态规划是求解决策过程最优化的数学方法.利用各个阶段之间的关系,逐个求解,最终求得全局 ...