二叉查找树(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. SAP ABAP 日期,时间 相关函数

    获的两个日期之间的分钟数 data min TYPE i. CALL FUNCTION 'DELTA_TIME_DAY_HOUR' EXPORTING T1 = ' T2 = ' D1 = ' D2 ...

  2. ABAP术语-Error Message

    Error Message 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/30/1058283.html Information from ...

  3. linux下进程的最大线程数、进程最大数、进程打开的文件数

    linux下进程的最大线程数.进程最大数.进程打开的文件数   ===========最大线程数============== linux 系统中单个进程的最大线程数有其最大的限制 PTHREAD_TH ...

  4. maven-认识

    1.认识maven maven是强大的项目构建工具,也是依赖管理工具 使用maven前提是安装JDK maven非常重要配置文件:setting.xml 3.maven工程 maven工程的约束: 主 ...

  5. PHP判断URL地址百度是否已经收录并主动提交MIP数据

    /** * PHP检测URL地址百度是否已经收录 * @param string $url 要检测的URL地址 */ function Baidu($url) { $url = 'http://www ...

  6. 利用phpspreadsheet切割excel大文件

    背景: 利用phpspreadsheet可以轻松的解析excel文件,但是phpspreadsheet的内存消耗也是比较大的,我试过解析将近5M的纯文字excel内存使用量就会超过php默认的最大内存 ...

  7. YSZOJ:#247. [福利]可持久化线段树 (最适合可持久化线段树入门)

    题目链接:https://syzoj.com/problem/247 解题心得: 可持久化线段树其实就是一个线段树功能的加强版,加强在哪里呢?那就是如果一颗普通的线段树多次修改之后还能知道最开始的线段 ...

  8. struts2官方 中文教程 系列七:消息资源文件

    介绍 在本教程中,我们将探索使用Struts 2消息资源功能(也称为 resource bundles 资源绑定).消息资源提供了一种简单的方法,可以将文本放在一个视图页面中,通过应用程序,创建表单字 ...

  9. 详解jQuery中 .bind() vs .live() vs .delegate() vs .on() 的区别

    转载自:http://zhuzhichao.com/2013/12/differences-between-jquery-bind-vs-live/ 我见过很多开发者很困惑关于jQuery中的.bin ...

  10. lnmp操作

    LNMP 1.2+状态管理: lnmp {start|stop|reload|restart|kill|status}LNMP 1.2+各个程序状态管理: lnmp {nginx|mysql|mari ...