二叉搜索树

96. 不同的二叉搜索树

偶尔善良 提交于 2020-02-07 00:43:49
思路 : 参考解答 假设 n 个节点存在二叉排序树的个数是 G(n) ,令 f(i) 为以 i 为根的二叉搜索树的个数,则: G(n)=f(1)+f(2)+f(3)+f(4)+...+f(n) 当 i 为根节点时,其左子树节点个数为 i-1 个,右子树节点为 n-i ,则: f(i)=G(i−1)∗G(n−i) 综合两个公式可以得到 卡特兰数 公式: G(n)=G(0)∗G(n−1)+G(1)∗G(n−2)+...+G(n−1)∗G(0) 递推公式: class Solution : def numTrees ( self , n : int ) - > int : # f(j)=G(j−1)∗G(i−j) # G(i)=f(1)+f(2)+f(3)+f(4)+...+f(i) if n <= 1 : return 1 G = [ 0 for _ in range ( n + 1 ) ] G [ 0 ] , G [ 1 ] = 1 , 1 for i in range ( 2 , n + 1 ) : # 求解G[2]到G[n] for j in range ( 1 , i + 1 ) : # 叠加求G[i] G [ i ] += G [ j - 1 ] * G [ i - j ] return G [ n ] 来源: CSDN 作者: 三岁与十八 链接: https://blog

牛客 二叉搜索树与双向链表

泄露秘密 提交于 2020-02-06 18:34:30
题目要求: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 解题思路: 思路1: 我们知道双向链表中,每个结点有两个指针域,一个指向前一个结点,一个指向后一个结点。而在二叉树中同样也有两个指针域,一个指向左孩子,一个指向右孩子。所以二叉树和双向链表结构上是相似的。又因为二叉搜索树中,左孩子一定小于父节点,右孩子一定能够大于父节点。所以我们可以将原先指向左孩子的指针当做是链表中指向前一个结点的指针,将原先指向右孩子的指针当做是链表中指向后一个结点的指针。如图: 题目要求转换后是有序的双向链表,因为二叉搜索树的中序遍历是有序的,所以采用中序遍历来完成。当遍历到根节点的时候,只需将根和左子树最大的一个结点链接起来,将跟结点和右子树最小的一个结点链接起来即可。如图: 按照中序遍历递归,当遍历到根结点的时候,说明此事根结点的左子树已经是有序的双向链表了,并且此时链表尾部的值为左子树的最大值。我们将其与根结点链接起来,此时根结点变成了尾部,我们知道根结点后面的节点是右子树最小的结点,将其与根结点链接起来,再继续递归即可解决问题。 代码: class solution1 { TreeNode * head = nullptr ; //进行链接的头 TreeNode * realhead = nullptr ; /

数据结构与算法之二叉搜索树

纵饮孤独 提交于 2020-02-06 05:09:33
二叉搜索树 二叉搜索树又称为二叉排序树,首先二叉搜索树是一棵二叉树,所谓二叉树,就是"任意节点最多允许两个子节点",这两个子节点称为左右子节点。 性质: 若左子树非空,则左子树上的所有节点均小于其根节点 若右子树非空,则右子树上的所有节点均大于其根节点 即任意节点的值一定大于其左子树中的每一个节点的值,并小于右子树中的每一个节点的值。换句话说, 中序遍历二叉搜索树得到的序列为从小到大排序的有序序列。 二叉搜索树基本实现: //二叉搜索树的实现 #include<iostream> using namespace std; struct Node{ int data;//数据 struct Node *lchild;//左孩子结点 struct Node *rchild;//右孩子结点 Node(int x):data(x),lchild(nullptr),rchild(nullptr){}; }; //从二叉树中搜索对应的val值,如果存在在返回该结点,若不存在则返回空指针 Node* SearchBST(Node* root,int val) { while(root!=nullptr) { if(root->data == val) return root; root = root->data > val?root->lchild:root->rchild; } return

PTA 7-4 是否同一棵二叉搜索树 (25分)

我们两清 提交于 2020-02-06 03:46:00
给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{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 解法: 首先根据输入的初始序列创建初始二叉搜索树,然后再根据输入的每一组需要检查的序列创建需要检查的二叉搜索树,再利用递归遍历两初始二叉树和检查二叉树,比较每一个对应的节点数值是否相等。 #include<iostream> #include<malloc.h> using namespace std; struct

938. 二叉搜索树的范围和

孤街醉人 提交于 2020-02-05 03:02:24
给定二叉搜索树的根结点 root,返回 L 和 R(含)之间的所有结点的值的和。 二叉搜索树保证具有唯一的值。 示例 1: 输入:root = [10,5,15,3,7,null,18], L = 7, R = 15 输出:32 1.利用BST中序遍历有序这一特点 2.根据BST的性质 # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution(object): def rangeSumBST(self, root, L, R): """ :type root: TreeNode :type L: int :type R: int :rtype: int """ if not root: return 0 def t(root): if not root: return 0 t(root.left) if L<=root.val<=R: self.res += root.val t(root.right) self.res = 0 t(root) return self.res # Definition for a binary

二叉搜索树(Binary Search Tree)

元气小坏坏 提交于 2020-02-02 22:09:43
一、基本概念 1. 二叉树 和链表一样,具有动态的数据结构; 具有唯一的根节点; 每个节点最多有两个子节点,最多有一个父节点; 每个节点的左子树也是二叉树,每个节点的右子树也是二叉树; 一个节点或者空也是二叉树; 2.二分搜索树 二分搜索树属于二叉树的一种; 每个节点的值 大于其左子树的所有节点; 小于其右子树的所有节点; 每个子树也是二分搜索树; 每个节点所存储的元素必须有可比较性 ; 二、二分搜索树的代码实现 1. 基础代码 此处限制了二叉搜索树所支持的泛型,需要继承Comparable类,即该类需要满足可比较性 //此处限制了二叉搜索树所支持的泛型,需要继承Comparable类,即该类需要满足可比较性 public class BSTree < E extends Comparable < E > > { //使用内部类定义节点的概念; private class Node { public E e ; public Node left , right ; public Node ( E e ) { this . e = e ; this . left = null ; this . right = null ; } } //根节点 private Node root ; //记录二叉树存储元素的个数 private int size ; //无参构造方法 public

是否二叉搜索树

痞子三分冷 提交于 2020-02-01 22:13:04
习题4.3 是否二叉搜索树 (25分) 本题要求实现函数,判断给定二叉树是否二叉搜索树。 函数接口定义: bool IsBST ( BinTree T ) ; 其中 BinTree 结构定义如下: typedef struct TNode * Position ; typedef Position BinTree ; struct TNode { ElementType Data ; BinTree Left ; BinTree Right ; } ; 函数 IsBST 须判断给定的 T 是否二叉搜索树,即满足如下定义的二叉树: 定义:一个二叉搜索树是一棵二叉树,它可以为空。如果不为空,它将满足以下性质: 非空左子树的所有键值小于其根结点的键值。 非空右子树的所有键值大于其根结点的键值。 左、右子树都是二叉搜索树。 如果 T 是二叉搜索树,则函数返回true,否则返回false。 裁判测试程序样例: # include <stdio.h> # include <stdlib.h> typedef enum { false , true } bool ; typedef int ElementType ; typedef struct TNode * Position ; typedef Position BinTree ; struct TNode { ElementType

二叉搜索树与平衡二叉树

北城余情 提交于 2020-01-31 04:51:54
二叉搜索树 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 定义 二叉搜索树是一种节点值之间具有一定数量级次序的二叉树,对于树中每个节点: 若其左子树存在,则其左子树中每个节点的值都不大于该节点值; 若其右子树存在,则其右子树中每个节点的值都不小于该节点值。 示例: 平衡二叉树 平衡二叉树(Balanced Binary Tree)具有以下性质: 它是一棵空树或它的左右两个子树的高度差的绝对值不超过1, 并且左右两个子树都是一棵平衡二叉树。 平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。 最小二叉平衡树的节点的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。 如下图所示,左图是一棵平衡二叉树,根节点10,左右两子树的高度差是1,而右图,虽然根节点左右两子树高度差是0,但是右子树15的左右子树高度差为2,不符合定义,所以右图不是一棵平衡二叉树。 来源: CSDN 作者: 飞飞晗 链接: https://blog.csdn.net/weixin_42247922/article/details/104110921

NowCoder 二叉搜索树的后序遍历序列 递归

拈花ヽ惹草 提交于 2020-01-31 03:03:42
题意:给一串序列,判断该序列是否某二叉树的后序遍历序列 思路:后序遍历最后一个节点为根节点,前面的都可以分成连续的两部分,一部分比根节点小,另一部分比根节点大,依次分块递归判断两部分是否连续即可 public class Solution { public boolean VerifySquenceOfBST ( int [ ] sequence ) { if ( sequence == null || sequence . length == 0 ) return false ; return solve ( sequence , 0 , sequence . length - 1 ) ; } public boolean solve ( int [ ] a , int l , int r ) { if ( l >= r ) return true ; int i = l , root = a [ r ] , mid ; for ( ; i < r ; i ++ ) { if ( a [ i ] > root ) break ; } mid = i ; for ( ; i < r ; i ++ ) { if ( a [ i ] < root ) return false ; } return solve ( a , l , mid - 1 ) && solve ( a , mid

数据结构:二叉搜索树实现

孤街浪徒 提交于 2020-01-30 17:53:50
循关键码访问 call-by-key 大小比较,相等比对 词条 template < typename K , typename V > struct Entry { K key ; V value ; Entry ( K k = K ( ) , V v = V ( ) ) : key ( k ) , value ( v ) { } ; //默认构造函数 Entry ( Entry < K , V > const & e ) : key ( e . key ) , value ( e . value ) { } ; //克隆 /*还有一些比较的接口*/ bool operator < ( Entry < K , V > const & e ) { return key < e . key ; } //小于 bool operator > ( Entry < K , V > const & e ) { return key > e . key ; } //大于 bool operator == ( Entry < K , V > const & e ) { return key == e . key ; } //等于 bool operator != ( Entry < K , V > const & e ) { return key != e . key ; } //不等于 }