二叉搜索树

C++ 二叉搜索树原理及其实现

做~自己de王妃 提交于 2019-12-22 00:05:44
首先是概念: 二叉搜索树又称二叉排序树,它具有以下的性质: 若是左子树不为空,则左子树上所有节点的值小于根节点的值 若是右子树不为空,则右子树上所有结点的值大于根节点的值 二叉搜索树的左右子树也是二叉搜索树 二叉搜索树的中序排列是一个有序数列 再下来是它的实现 首先是构造节点: template<class K> struct BStreeNode{ BStreeNode(const K& date = K()) //节点的定义 :leftC(nullptr), // 初始化 rightC(nullptr), date_(date) {} BStreeNode<K> *leftC; //左孩子 BStreeNode<K> *rightC; //右孩子 K date_; }; 二叉搜索树类的实现: template<class K> class BStree{ typedef BStreeNode<K> BsNode; public: BStree() : _root(nullptr) {} BsNode* Find(const K& date){ //查找节点 BsNode* pNode = _root; while (pNode){ if (pNode->date_ == date){ return pNode; } else if (pNode->date_ > date){

24.输入一个二叉搜索树,将该树转换为一个排序的双向链表

落爺英雄遲暮 提交于 2019-12-21 07:13:14
package java2019 ; import java . util . Stack ; //输入一个二叉搜索树,将该树转换为一个排序的双向链表(不创建新的节点,只能调整树中节点指针的指向) //核心是中序遍历非递归算法 //修改当前遍历节点与前一遍节点的指针指向 public class Demo24 { //中序非递归算法 public void InorderTravel ( TreeNode root ) { Stack < TreeNode > stack = new Stack < TreeNode > ( ) ; TreeNode p = root ; while ( p != null || ! stack . empty ( ) ) { while ( p != null ) { //一直向左并将沿途节点压入堆栈 stack . push ( p ) ; p = p . left ; } p = stack . pop ( ) ; System . out . println ( p . val + " " ) ; p = p . right ; } } //前序非递归算法 public void PreorderTravel ( TreeNode root ) { Stack < TreeNode > stack = new Stack <

二叉搜索树的模拟实现与总结

可紊 提交于 2019-12-21 02:48:05
什么是二叉搜索树? 二叉搜索树又称二叉排序树。(⚠️: 空树也是一颗二叉搜索树 ) 二叉搜索树的 性质 : 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值。 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值。 他的左右子树也分别为二叉搜索树。 如何 验证 一个树是不是二叉搜索树? 搜索二叉搜索树的中序遍历一定是一个有序的数据集合。 二叉搜索树的最左边节点一定是最小的节点。 二叉搜索树的最右边节点一定是最大的节点。 二叉搜索树的 性能分析 : 二叉搜索树的插入和删除都必须先查找,因此,查找效率便代表了二叉搜索树中各个操作的性能。 假设有一个n个节点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是节点在二叉搜索树的深度的函数,即节点越深,则比较次数越多。 但是对于一个数据集合,插入顺序不同,可能得到不同结构的二叉搜索树。 例:有数据集合 int a[7] = {3,4,5,6,7,8,9}; 1、右单支二叉搜索树{3,4,5,6,7,8,9} 2、完全二叉树{6,4,3,5,8,7,9} 性能分析: 最优情况下,二叉搜索树为完全二叉树,平均比较次数为:lgN(注:这里是log以二为底的N) 最差情况下,二叉搜索树为右单支,平均比较次数为:N/2; 二叉搜索树的 模拟实现 : //二叉搜索树(binary search tree) #include

LeetCode 98. 验证二叉搜索树(Validate Binary Search Tree)

瘦欲@ 提交于 2019-12-18 15:14:51
题目描述 给定一个二叉树,判断其是否是一个有效的二叉搜索树。 假设一个二叉搜索树具有如下特征: 节点的左子树只包含 小于 当前节点的数。 节点的右子树只包含 大于 当前节点的数。 所有左子树和右子树自身必须也是二叉搜索树。 示例 1: 输入: 2 / \ 1 3 输出: true 示例 2: 输入: 5 / \ 1 4 / \ 3 6 输出: false 解释: 输入为: [5,1,4,null,null,3,6]。 根节点的值为 5 ,但是其右子节点值为 4 。 解题思路 用树的后序遍历思想,对于每次遍历到的根节点,根据左右子树是否为BST分为四种情况: 若左右子树都不为空,则分别递归判断左右子树是否为BST,并且分别传回左右子树的最小值和最大值。若左右子树都为BST,则比较左子树最大值是否小于根结点值以及右子树最小值是否小于根结点值,满足则为BST并记录本子树的最小值与最大值,否则整棵树不是BST 若左子树为空右子树不为空,则判断右子树是否为BST, 并且传回右子树的最小值和最大值。若右子树为BST,则比较右子树 最小值是否小于根结点值,满足则为BST并记录本子树的最小值与最大值,否则整棵树不是BST 若右子树为空左子树不为空,则判断左子树是否为BST, 并且传回左子树的最小值和最大值。若左子树为BST,则比较左子树 最小值是否小于根结点值

数据结构-二叉搜索树(BST binary search tree)

醉酒当歌 提交于 2019-12-18 05:51:32
本文由 @呆代待殆 原创,转载请注明出处: http://www.cnblogs.com/coffeeSS/ 二叉搜索树简介 顾名思义,二叉搜索树是以一棵二叉树来组织的,这样的一棵树可以用一个链表数据结构来表示,每个节点除了key和卫星数据(除了二叉树节点的基本数据以外人为添加的数据,这些数据和树的基本结构无关),还有left、right、parent,分别指向节点的左孩子、右孩子和父节点,如果对应的节点不存在则指向NIL节点(因为最简单的二叉搜索树中的NIL节点里并没有有用的信息,所以在实现的时候简单的指向null也可以,本文的代码部分就会这么处理)。 二叉搜索树的性质 1,任意节点x,其左子树中的key不大于x.key,其右子树中的key不小于x.key。 2,不同的二叉搜索树可以代表同一组值的集合。 3,二叉搜索树的基本操作和树的高度成正比,所以如果是一棵 完全二叉树 的话最坏运行时间为 Θ(lg n ) ,但是若是一个n个节点连接成的 线性树 ,那么最坏运行时间是 Θ( n ) 。 4,根节点是唯一一个parent指针指向NIL节点的节点。 5,每一个节点至少包括key、left、right与parent四个属性,构建二叉搜索树时,必须存在针对key的比较算法。 下面给出一张wiki百科上的二叉搜索树的图示 二叉搜索树的操作 二叉搜索树的基本结构(C++) 1 //节点结构

是否同一棵二叉搜索树

一世执手 提交于 2019-12-16 19:21:05
是否同一棵二叉搜索树 问题描述 输入格式 输出格式 输入样例 输出样例 C语言代码 问题描述 给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。 输入格式 输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后L行,每行给出N个插入的元素,属于L个需要检查的序列。 简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理。 输出格式 对每一组需要检查的序列,如果其生成的二叉搜索树跟对应的初始序列生成的一样,输出“Yes”,否则输出“No”。 输入样例 4 2 3 1 4 2 3 4 1 2 3 2 4 1 2 1 2 1 1 2 0 输出样例 Yes No No C语言代码 # include <stdio.h> # include <stdlib.h> typedef struct tree * tree ; struct tree { int v ; tree left , right ;

98_验证二叉搜索树

旧城冷巷雨未停 提交于 2019-12-15 16:23:41
""" 给定一个二叉树,判断其是否是一个有效的二叉搜索树。 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数。 节点的右子树只包含大于当前节点的数。 所有左子树和右子树自身必须也是二叉搜索树。 """ from TreeNode import TreeNode # 递归 def isValidBST1 ( root ) : def helper ( node , lower = float ( "-inf" ) , upper = float ( "inf" ) ) : if not node : return True val = node . val if val <= lower or val >= upper : return False if not helper ( node . right , val , upper ) : return False if not helper ( node . left , lower , val ) : return False return True return helper ( root ) # 时间复杂度:o(N) 每个节点访问一次 # 空间复杂度:o(N) 我们跟进了整棵树 # 迭代 def isValidBST2 ( root ) : if not root : return True stack

leetcode95.不同的二叉搜索树 II

随声附和 提交于 2019-12-15 09:02:39
给定一个整数 n,生成所有由 1 … n 为节点所组成的二叉搜索树。 示例: 输入 : 3 输出 : [ [ 1 , null , 3 , 2 ] , [ 3 , 2 , null , 1 ] , [ 3 , 1 , null , null , 2 ] , [ 2 , 1 , 3 ] , [ 1 , null , 2 , null , 3 ] ] 解释: 以上的输出对应以下 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/unique-binary-search-trees-ii 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 完整代码 参考: leetcode题解 递归构建 基本思想:循环构建以每一个节点为根的二叉搜索树,以递归的形式构建树的左右子树 说明:递归函数传入的参数(二叉搜索树的起始节点(s)和终止节点(e)) 递归终止条件:s>e:在结果序列中存入空节点;s=e:将该节点存入结果序列中 循环构建以节点i为根节点的二叉搜索树: 递归构建左子二叉搜索树 递归构建右子二叉搜索树 合并成以i为根的二叉搜索树 /** * Definition for a binary

简单易懂带你了解二叉树

巧了我就是萌 提交于 2019-12-12 19:31:37
前言 上一篇博客为大家介绍了 数组与链表 这两种数据结构,虽然它们在某些方面有着自己的一些优点,但是也存在着一些自身的缺陷,本篇博客为将为大家介绍一下数据结构--- 二叉树 ,它在保留数组和链表的优点的同时也改善了它们的缺点(当然它也有着自己的缺点,同时它的实现也比较复杂). 1. 数组和链表的特点 数组的优点: 简单易用. 无序数组的插入速度很快,效率为O(1) 有序数组的查找速度较快(较无序数组),效率为O(logN) 数组的缺点: 数组的查找、删除很慢 数组一旦确定长度,无法改变 链表的优点: 可以无限扩容(只要内存够大) 在链表头的新增、删除很快,效率为O(1) 链表的缺点: 查找很慢 在非链表头的位置新增、删除很慢,效率为O(N) 2.树和二叉树 树是一种数据结构,因为它数据的保存形式很像一个树,所以得名为树(树状图). 而二叉树是一种特殊的树, 它的每个节点最多含有两个子树 ,现实世界中的二叉树: 图1 但是实际中的二叉树却是 倒挂 的,如图: 图2 二叉树的名词解释: 根:树顶端的节点称为根。一棵树只有一个根,如果要把一个节点和边的集合称为树,那么从根到其他任何一个节点都必须有且只有一条路径。A是根节点。 父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;B是D的父节点。 子节点:一个节点含有的子树的根节点称为该节点的子节点;D是B的子节点。 兄弟节点

二叉搜索树结点最小距离

此生再无相见时 提交于 2019-12-11 22:07:07
给定一个二叉搜索树的根结点 root, 返回树中任意两节点的差的最小值。 示例: 输入: root = [4,2,6,1,3,null,null] 输出: 1 解释: 注意,root是树结点对象(TreeNode object),而不是数组。 给定的树 [4,2,6,1,3,null,null] 可表示为下图: 4 / \ 2 6 / \ 1 3 最小的差值是 1, 它是节点1和节点2的差值, 也是节点3和节点2的差值。 注意: 二叉树的大小范围在 2 到 100。 二叉树总是有效的,每个节点的值都是整数,且不重复。 思路:中序遍历,因为搜索二叉树中序遍历后是升序的,所以最小差值一定存在于中序中相邻的结点之间;刚开始我用的后序遍历,当访问到根结点是此时计算根结点与左右子树结点的差值,此时会出现一个问题,比如:最小的差值不存在于任意结点与其左右子树之间,而是存在于根结点与左子树的最右结点之间(或根结点与其右子树的最左结点之间),此时无法正确的得出结果。 code1:中序遍历时把结点加入vector中,然后找出数组中相邻结点的最小差值 code2:中序遍历,边遍历,边求解 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right;