二叉查找树是一种关键字有序存放的二叉树。在不含重复关键字的二叉查找树中,关键字"较小"的节点一定在关键字“较大”的节点的左子树中,“较小”一般可以由内值类型的<运算符来实现,或由重载了<运算符的类类型的<运算符来实现。“较小”的概念可以根据我们的需要有不同的实现。本文实现一个关键字类型为elemType的二叉查找树,elemType可以是内置类型,也可以是自定义类型,如果是自定义类型,二叉查找树要求类型实现一些比较运算符,能够定义"较大"、“较小”、”相等“、”不等“这些概念。

本文实现操作:

1. 层序遍历  2. 插入  3.删除

4.查找     5. 根据若干给定元素建树

0. 二叉查找树的定义

//binary tree
struct binTree
{
elemType data;  
binTree* lchild;
binTree* rchild;
binTree(elemType data):data(data),lchild(NULL),rchild(NULL) {};
};

1. 层序遍历

这里使用队列来实现层序遍历。并接受一个void (*) (const binTree* root) 类型的函数指针作为参数,定义遍历节点时要对节点进行的操作。

//层序遍历,对每一个节点执行函数指针pfun指定的操作
void layerOrderTravel(const binTree * root,void (*pfun) (const binTree* root) )
{
if( root == NULL ) return ;
std::queue<const binTree*> q;
q.push(root);
while(!q.empty())
{
const binTree* node = q.front();
if( node->lchild != NULL ) q.push(node->lchild);
if( node->rchild != NULL ) q.push(node->rchild);
pfun(node);
q.pop();
}
return ;
}

2. 插入

//在根为root的二叉查找树树中插入元素为x的节点
void BSTInsert(binTree*& root,elemType x)
{
//root==NULL即找到了插入位置
if( root == NULL )
{
root = new binTree(x);
//cout << "正在插入" << x << endl;
return ;
}
//对于不允许重复元素的树,若x已存在,直接返回。
if( root->data == x ) return ;
//在左子树中插入
if( x < root->data )
BSTInsert(root->lchild,x);
//在右子树中插入
if( x > root->data )
BSTInsert(root->rchild,x);
}

3. 删除

//在root中删除值为x的节点
void BSTDelete(binTree*& root,elemType x)
{
//
if( root == NULL ) return ;
//找到了要删除的节点
if( root->data == x )
{
if( root->lchild == NULL && root->rchild == NULL )
{
//节点没有左右孩子,直接将该节点指针置空,其父节点中指向这个节点的lchild或rchild会相应地指向NULL
root = NULL;
return ;
}
//如果有左孩子,令其直接前驱代替其值,并递归地在左子树中删除其直接前驱
else if( root->lchild != NULL )
{
binTree* node = root->lchild;
while( node->rchild )
node = node->rchild;
root->data = node->data;
BSTDelete(root->lchild,node->data);
}
else if( root->rchild != NULL )
{
binTree* node = root->rchild;
while( node->lchild )
node = node->lchild;
root->data = node->data;
BSTDelete(root->rchild,node->data);
}
}
else if( x < root->data ) BSTDelete(root->lchild,x);
else if( x > root->data ) BSTDelete(root->rchild,x);
}

4. 查找

//在根为root的树中查找值为x的节点
binTree* BSTFind( binTree* root,elemType x)
{
if( root == NULL )
{
std::cout << "空树" << std::endl;
//throw
return NULL;
}
//找到了
if( root->data == x )
return root;
//在右子树中查找
if( root->data < x )
return BSTFind(root->rchild,x);
//在左子树中查找
if( root->data > x )
return BSTFind(root->lchild,x); //throw
return NULL;
}

5. 建树

//由给定的元素序列elems创建一棵二叉查找树,返回树根节点的指针
binTree* createBST(const std::vector<elemType>& elems)
{
binTree* root = NULL;
for( std::vector<elemType>::const_iterator it = elems.begin(); it != elems.end(); ++it )
{
BSTInsert(root,*it);
}
return root;
}

二叉查找树的实现C/C++的更多相关文章

  1. 数据结构:二叉查找树(C语言实现)

    数据结构:二叉查找树(C语言实现) ►写在前面 关于二叉树的基础知识,请看我的一篇博客:二叉树的链式存储 说明: 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: 1.若其左子树不空,则左子树上 ...

  2. 数据结构笔记--二叉查找树概述以及java代码实现

    一些概念: 二叉查找树的重要性质:对于树中的每一个节点X,它的左子树任一节点的值均小于X,右子树上任意节点的值均大于X. 二叉查找树是java的TreeSet和TreeMap类实现的基础. 由于树的递 ...

  3. codevs 1285 二叉查找树STL基本用法

    C++STL库的set就是一个二叉查找树,并且支持结构体. 在写结构体式的二叉查找树时,需要在结构体里面定义操作符 < ,因为需要比较. set经常会用到迭代器,这里说明一下迭代器:可以类似的把 ...

  4. 平衡二叉查找树(AVL)的理解与实现

    AVL树的介绍 平衡二叉树,又称AVL(Adelson-Velskii和Landis)树,是带有平衡条件的二叉查找树.这个平衡条件必须要容易保持,而且它必须保证树的深度是 O(log N).一棵AVL ...

  5. 二叉查找树 C++实现(含完整代码)

    一般二叉树的查找是通过遍历整棵二叉树实现,效率较低.二叉查找树是一种特殊的二叉树,可以提高查找的效率.二叉查找树又称为二叉排序树或二叉搜索树. 二叉查找树的定义 二叉排序树(Binary Search ...

  6. 数据结构——二叉查找树、AVL树

    二叉查找树:由于二叉查找树建树的过程即为插入的过程,所以其中序遍历一定为升序排列! 插入:直接插入,插入后一定为根节点 查找:直接查找 删除:叶子节点直接删除,有一个孩子的节点删除后将孩子节点接入到父 ...

  7. Java for LintCode 验证二叉查找树

    给定一个二叉树,判断它是否是合法的二叉查找树(BST) 一棵BST定义为: 节点的左子树中的值要严格小于该节点的值.    节点的右子树中的值要严格大于该节点的值.    左右子树也必须是二叉查找树. ...

  8. 数据结构和算法 – 9.二叉树和二叉查找树

      9.1.树的定义   9.2.二叉树 人们把每个节点最多拥有不超过两个子节点的树定义为二叉树.由于限制子节点的数量为 2,人们可以为插入数据.删除数据.以及在二叉树中查找数据编写有效的程序了. 在 ...

  9. 二叉树-二叉查找树-AVL树-遍历

    一.二叉树 定义:每个节点都不能有多于两个的儿子的树. 二叉树节点声明: struct treeNode { elementType element; treeNode * left; treeNod ...

  10. 二叉查找树的Java实现

    为了克服对树结构编程的恐惧感,决心自己实现一遍二叉查找树,以便掌握关于树结构编程的一些技巧和方法.以下是基本思路: [1] 关于容器与封装.封装,是一种非常重要的系统设计思想:无论是面向过程的函数,还 ...

随机推荐

  1. P2670 [NOIP2015 普及组] 扫雷游戏

    题目背景 NOIP2015 普及组 T2 题目描述 扫雷游戏是一款十分经典的单机小游戏.在 nn 行 mm 列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格).玩家翻开一 ...

  2. 基于wifi的音频采集及处理解决方案小结

    一沉浮    这些年,一直围绕着音频来做案子,做出来的案子自己都数不清楚了.记得前几年,刚出道的时候,就把wifi音频传输的设备做出来了.可惜的是,当初太超前市场了,鲜有人问.随着时间的推移,在疫情之 ...

  3. c语言中float和double类型的区别

    1.变量bai类型不同 float属于单du精度zhi型浮点数据. double属于双精度型浮点数据. 2.指数范围不同 float的指数范围为-127~128. double而double的指数范围 ...

  4. CSS(盒子模型其他样式、浮动、常见网页布局、清除浮动、ps切图、学成在线页页面展示)

    一.其他样式 1.圆角边框 在 CSS3 中,新增了圆角边框样式,这样我们的盒子就可以变圆角了. border-radius 属性用于设置元素的外边框圆角. 语法: border-radius:len ...

  5. 记录-使用双token实现无感刷新,前后端详细代码

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 近期写的一个项目使用双token实现无感刷新.最后做了一些总结,本文详细介绍了实现流程,前后端详细代码.前端使用了Vue3+Vite ...

  6. 记录--uni-app App端半屏连续扫码

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 本文用一个简单的 demo 讲解 App端 半屏连续扫码 的实现方式,包括(条形码.二维码等各种各样的码). 我会从实现思路讲起,如果你比 ...

  7. IPython刷新函数模块

    技术背景 IPython是一个非常灵活好用的python终端工具,而且比Python自带的终端工具还多了命令行高亮和自动索引的功能,也是常用的Jupyter Notebook的基础工具.在使用IPyt ...

  8. Oracle限制某个帐号只能在特定机器上访问数据库

    CREATE OR REPLACE TRIGGER logon_ip_control AFTER logon ON user_test.schema BEGIN IF USER IN ('user_t ...

  9. mybatis xml 文件 sql include 的用法

    mybatis xml 文件中对于重复出现的sql 片段可以使用标签提取出来,在使用的地方使用标签引用即可具体用法如下: <sql id="Base_Column_List" ...

  10. 【Java】快速排序

    代码: 1 public static void quickSort(int[] arr) { 2 if (arr == null || arr.length < 2) { 3 return; ...