与链表不同,树是一种非线性的数据结构。树中最常用的是二叉树,二叉树限制了子树的数量,也就是每个结点的子树至多2个,并且这两个子树是有顺序的。而二叉搜索树(二叉查找树,二叉排序树)是指根节点的关键字大于左子树的,而小于右子树,并且,左右子树也是一颗二叉搜索树。也就是说中序遍历一颗二叉搜索树,它的输出是从小到大排序好的。

  除了普通的二叉搜索树之外,还有很多关于它的变形。

  二叉平衡搜索树,即即是一颗二叉平衡树,也是一颗搜索树,平衡树即任意一个结点的左子树的高度与右子树的高度之差的绝对值不大于1。

  红黑树,也是一种特殊的二叉查找树,除了具备查找树的特点,它的每个结点上还有一个记录红黑颜色的元素。

  这里我们主要讨论一般的二叉搜索树。

  二叉搜索树,其实就是一颗特殊的树,任何适用于树的算法都适用于二叉搜索树。当然它也是图,任何适用于图的算法也适用于二叉搜索树。图中的深度优先搜索(DFS)其实就是树中的前序遍历,广度优先搜索(BFS)就是树中的层序遍历。当然图中还有很多其他算法也都适用于树。

1、二叉树的数据结构

typedef struct binSrcTreeNode{int element;struct binSrcTreeNode *pLeft;struct binSrcTreeNode *pRight;
}BSTNode;

2、动态分配一个二叉树的结点

BSTNode* allocNode(int element){BATNode *pNode = (BSTNode*)malloc(sizeof(BSTNode));if(NULL != pNode){pNode->element = element;pNode->pLeft = NULL;pNode->pRight = NULL;}return pNode;
}

3、二叉搜索树的查找

由于二叉搜索树是已经排序了的二叉树,所以可以通过二分查找来搜索。先判断是否等于根节点,如果大于根节点的关键字,搜索右子树,小于根节点的关键字,搜索左子树。

bool searchInBSTree(const BSTNode *pRoot,int element,BSTNode **pNode){if(NULL == pRoot)return false;*pNode = pRoot;if(pRoot->element == element){return true;}else if(pRoot->element > element)return searchInBSTree(pRoot->pLeft,element,pNode);elsereturn searchInBSTree(pRoot->pRight,element,pNode);
}

4、二叉搜索树的插入

首先查找二叉树是是否已经存在该元素,如果已经存在返回false;如果不存在,插入该结点,插入元素大于根节点,则插入右子树,否则,插入左子树中。

bool insertIntoBSTree(BSTNode **pRoot,int element){if(NULL == pRoot)return false;if(NULL == *pRoot){*pRoot = allocNode(element);return NULL==*pRoot?false:true;}BSTNode **pSrc = NULL;if(searchInBSTree(pRoot,element,pSrc))return false;BSTNode *pNode = allocNode(element);if(element < *pSrc->element)*pSrc->pLeft = pNode;else*pSrc->pRight = pNode;return true;
}

5、二叉搜索树的删除

二叉搜索树的删除分为三种情况:

(1) 删除结点为叶子结点,直接删除该结点,再修改其父结点的指针(注意分是根结点和不是根节点)。

(2) 删除结点为单支结点(即只有左子树或右子树)。

(3) 删除结点的左子树和右子树均不空。

bool deleteFromBSTree(BSTNode **pRoot,int element){if(NULL == pRoot || NULL == *pRoot)return false;BSTNode **pSrc = NULL;BSTNode **pParent = NULL;if(searchInBSTree(*pRoot,element,pParent,pSrc)){if(NULL == *pSrc->pLeft && NULL == *pSrc->pRight){free(*pSrc);*pSrc = NULL;return true;}else if(NULL == *pSrc->pLeft){if(*pSrc == *pParent->pLeft)*pParent->pLeft = *pSrc->pRight;else if(*pSrc == *pParent->pRight)*pParent->pRight = *pSrc->pRight;free(*pSrc);return true;}else if(NULL == *pSrc->pRight){if(*pSrc == *pParent->pLeft)*pParent->pLeft = *pSrc->pLeft;else if(*pSrc == *pParent->pRight)*pParent->pRight = *pSrc->pLeft;free(*pSrc);return true;}else{BSTNode *pNode = *pSrc;BSTNode *pChild = *pSrc->pLeft;while(pChild->pRight){pNode = pChild;pChild = pChild->pRight;}if(pNode == *pSrc) pNode->pLeft = pChild->pLeft;else pNode->pRight = pChild->pLeft;if(*pSrc == *pParent->pLeft) *pParent->pLeft = pChild;else *pParent->pRight = pChild;pChild->pLeft = *pSrc->pLeft;pChild->pRight = *pSrc->pRight;return true;}}return false;
}

6、二叉搜索树的前序中序后序遍历

/* preOrder to traverse the binarySearchTree.*/
void preOrderBinarySearchTree(const BSTNode *pRoot){if(NULL == pRoot)return ;printf("%d ",pRoot->element);preOrderBinarySearchTree(pRoot->pLeft);preOrderBinarySearchTree(pRoot->pRight);
}/* inOrder to traverse the binarySearchTree.*/
void inOrderBinarySearchTree(const BSTNode *pRoot){if(NULL == pRoot)return ;inOrderBinarySearchTree(pRoot->pLeft);printf("%d ",pRoot->element);inOrderBinarySearchTree(pRoot->pRight);
}/* posOrder to traverse the binarySearchTree.*/
void posOrderBinarySearchTree(const BSTNode *pRoot){if(NULL == pRoot)return ;posOrderBinarySearchTree(pRoot->pLeft);posOrderBinarySearchTree(pRoot->pRight);printf("%d ",pRoot->element);
}

7、释放结点

void freeBinarySearchTree(BSTNode *pRoot){if(NULL == pRoot)return ;freeBinarySearchTree(pRoot->pLeft);freeBinarySearchTree(pRoot->pRight);free(pRoot);
}

完整代码详见:https://github.com/whc2uestc/DataStructure-Algorithm/tree/master/tree

转载于:https://www.cnblogs.com/whc-uestc/p/4638349.html

数据结构与算法之二叉搜索树相关推荐

  1. 《数据结构与算法之二叉搜索树(Java实现)》

    说在前头:本人为大二在读学生,书写文章的目的是为了对自己掌握的知识和技术进行一定的记录,同时乐于与大家一起分享,因本人资历尚浅,能力有限,文章难免存在一些错漏之处,还请阅读此文章的大牛们见谅与斧正.若 ...

  2. 数据结构与算法-平衡二叉搜索树

    平衡二叉搜索树 1.自平衡的二叉搜索树 2.平衡 (1)空树平衡 (2)非空树平衡 左右子树平衡 左右子树高度差绝对值 <= 1 3.平衡因子 左右子树的高度差的衡量值 -1 0 1 (一)平衡 ...

  3. 【数据结构与算法】二叉搜索树V2.0的Java实现

    更新说明 在二叉搜索树V1.0的编程实现中,我们实现了BST的查找.插入,左右儿子删除的功能,但写的确实很一般,这里就Update一下. 功能介绍 void insert(x) → Insert x ...

  4. 《数据结构与算法之二叉平衡树(AVL)》

    说在前头:本人为大二在读学生,书写文章的目的是为了对自己掌握的知识和技术进行一定的记录,同时乐于与大家一起分享,因本人资历尚浅,发布的文章难免存在一些错漏之处,还请阅读此文章的大牛们见谅与斧正.若在阅 ...

  5. 看动画学算法之:二叉搜索树BST

    文章目录 简介 BST的基本性质 BST的构建 BST的搜索 BST的插入 BST的删除 看动画学算法之:二叉搜索树BST 简介 树是类似于链表的数据结构,和链表的线性结构不同的是,树是具有层次结构的 ...

  6. 【数据结构与算法】二叉堆与二叉搜索树的区别

    问题描述 记得刚学习数据结构的时候,就容易混淆二叉堆和二叉搜索树,其实虽说堆也是一种完全二叉树,但二者差别还是挺大的,本文试做分析. 逻辑结构 二叉堆和二叉搜索树都是结点带权重,并在父子结点间满足某种 ...

  7. 算法篇 - 二叉搜索树

    前言 在前端的工作当中,二叉搜索树不怎么常见,虽然没有快排.冒泡.去重.二分.希尔等算法常见,但是它的作用,在某些特定的场景下,是非常重要的. 目前es6的使用场景比较多,所以我准备能用es6的地方就 ...

  8. 【数据结构与算法】二叉堆V2.0的Java实现

    更新说明 我们在此前已经编写过简单版的二叉大根堆V1.0,这次,换成二叉小根堆,命名为二叉堆V2.0. 大家也知道,堆是完全二叉树,存储方式借助动态数组实现顺序存储,依赖于父子结点之间的index关系 ...

  9. 【每日一算法】二叉搜索树结点最小距离

    微信改版,加星标不迷路! 每日一算法-二叉搜索树节点最小距离 作者:阿广 阅读目录 1 题目 2 解析 1 题目 给定一个二叉搜索树的根结点 root, 返回树中任意两节点的差的最小值. 示例: 输入 ...

最新文章

  1. Apache源码包在LINUX(CENTOS6.8)中的安装(出现问题及解决)
  2. 中国法院裁定:禁售部分型号苹果手机
  3. 拉格朗日 SVM KKT
  4. pdf 字体和图片抽取
  5. java web响应式框架_Web开发的十佳HTML5响应式框架
  6. 信息学奥赛一本通(1186:出现次数超过一半的数)
  7. python办公入门经典_Python3入门经典100例
  8. linux c 密码 星号,Linux C : 登录密码星号 * 显示,包含能回退 backspace
  9. 案例分享:巧用工具提升无源码系统的性能和稳定性
  10. 使用 WebSphere ESB 构建企业服务总线
  11. Modern Radar for Automotive Applications(用于汽车应用的现代雷达)
  12. 华为性格面试的技巧方法
  13. 【设计模式】适配器模式:如何巧妙地过滤游戏中的敏感词
  14. 计算机图片怎么截图快捷键,电脑怎么截图,常见的截图快捷键
  15. 【ArcGIS Pro二次开发】(15):用地用海名称和代码互转
  16. 主流车品牌魅力指数榜别克、东风日产、一汽丰田列前三;亚航推出东盟超级应用平台 | 美通企业日报...
  17. flutter手写画板,保存存成图片并上传到后台服务器
  18. android计算器开源小项目代码(附安装包.apk)
  19. Java中随机数的产生方法
  20. 全国大学生FPGA创新设计竞赛:FPGA—相位干涉仪测向算法

热门文章

  1. mysql-proxy完成mysql读写分离
  2. 今天开始写技术博客啦
  3. Scott Mitchell 的ASP.NET 2.0数据教程之三十九:: 在编辑和插入界面里添加验证控件...
  4. maven中出现 ‘dependencies.dependency.version‘ for xxxx:jar is missing
  5. 注册确认邮件中图片不显示的问题
  6. 37 Reasons why your Neural Network is not working
  7. tp5视图里写原生php,tp5中使用原生sql查询总结
  8. 【机器学习】LR的分布式(并行化)实现
  9. IP地址的简单说明---Linux学习笔记
  10. SpringBoot+webservice