二叉搜索树

[LeetCode] 96. 不同的二叉搜索树

别来无恙 提交于 2020-01-13 01:12:02
题目链接 : https://leetcode-cn.com/problems/unique-binary-search-trees/ 题目描述: 给定一个整数 n ,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 思路: 动态规划 假设 n 个节点存在 令 G(n) 的从 1 到 n 可以形成二叉排序树个数 令 f(i) 为以 i 为根的二叉搜索树的个数 即有: G(n) = f(1) + f(2) + f(3) + f(4) + ... + f(n) n 为根节点,当 i 为根节点时,其左子树节点个数为 [1,2,3,...,i-1] ,右子树节点个数为 [i+1,i+2,...n] ,所以当 i 为根节点时,其左子树节点个数为 i-1 个,右子树节点为 n-i ,即 f(i) = G(i-1)*G(n-i) , 上面两式可得: G(n) = G(0)*G(n-1)+G(1)*(n-2)+...+G(n-1)*G(0) 相关题型: 95. 不同的二叉搜索树 II 代码: class Solution: def numTrees(self, n: int) -> int: dp

刷题笔记:二叉树的后序遍历序列(C++)

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-12 05:02:04
剑指offer刷题笔记 题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。 概念补充: 二叉搜索树的概念:它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉搜索树。 后序遍历:左子树→右子树→根节点 思路: 根据后序遍历的概念,序列的最后一个数字便是根节点的数字。 根据二叉搜索树的概念,通过与根节点的数字比较可以找到左右结点分水岭 根据二叉搜索树的左右子树仍然是二叉搜索树,可以通过递归判断左右子树是否同时为二叉搜索树 源代码: class Solution { public: bool VerifySquenceOfBST(vector<int> sequence) { return bst(sequence,0,sequence.size()-1); } private: bool bst(vector<int> seq,int begin,int end){ if(seq.empty()||begin>end){ return false; } int root=seq[end]; //根结点 int i=0; /

96. 不同的二叉搜索树

只愿长相守 提交于 2020-01-12 00:55:55
给定一个整数 n ,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3思路:根节点有左子树和右子树,n个节点的二叉树除去根节点还有n-1个节点,左子树和右子树一共n-1个节点,左子树和右子树的数量可以是(0,n-1),(1,n-2)...(n-1,0);   假设m个节点的二叉树有f(m)种,则总共种类数=[f(0)*f(n-1)]+[f(1)*f(n-2)]+...+[f(n-1)*f(0)] func numTrees(n int) int { dp:=make([]int,n+1) dp[0],dp[1]=1,1 for i:=2;i<=n;i++{ dp[i]=0 for j:=1;j<=i;j++{ dp[i]=dp[i]+dp[j-1]*dp[i-j] } } return dp[n] } 来源: https://www.cnblogs.com/fwdqxl/p/9353667.html

刷题笔记:二叉树与双向链表(C++)

﹥>﹥吖頭↗ 提交于 2020-01-11 18:54:20
剑指offer刷题笔记 题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 举例 思路 前面有道也是关于的二叉搜索树的笔记提到搜索二叉树的特点 左子树的数值小于根节点,右子树的数值大于根节点 二叉搜索树的子树也是二叉搜索树 根据上述的特点和所需要的有序结果,采取中序遍历的方式来遍历该二叉搜索树,便会得到一个有序的双向链表 按中序遍历完之后指针会知道链表中的最后一个结点,而需要返回表头,所以需要找到头结点 源代码: /* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } };*/ class Solution { public: TreeNode* Convert(TreeNode* pRootOfTree) { TreeNode* pLastNodeInList=NULL; //创建链表 ConvertNode(pRootOfTree,&pLastNodeInList); //找头节点 TreeNode* pHeadOfList=pLastNodeInList; while(pHeadOfList!

leetcode_99.恢复二叉搜索树

≡放荡痞女 提交于 2020-01-10 16:14:41
二叉搜索树中的两个节点被错误地交换。 请在不改变其结构的情况下,恢复这棵树。 示例 1: 输入: [1,3,null,null,2] 1 / 3 \ 2 输出: [3,1,null,null,2] 3 / 1 \ 2 示例 2: 输入: [3,1,4,null,null,2] 3 / \ 1 4 / 2 输出: [2,1,4,null,null,3] 2 / \ 1 4 / 3 解析:将二叉搜索树进行中序遍历得到的必然是一串严格递增的数组。 如果其中两个节点发生了交换,情况有两种: 1、相邻的两个节点交换例如 [1,2,4,3,5] 2、不相邻 [5,2,3,4,1] 观察两种情况的数字变化趋势,第一种情况中,出现了一次前一个数字比后一个数字大的现象,而第二种情况出现了两次。 因此定义两个节点,记录出现前一个数字大于后一个数字使得前后节点。 将这两个节点的值交换即可恢复二叉搜索树 class Solution { public : void recoverTree ( TreeNode * root ) { if ( root == 0 ) return ; stack < TreeNode * > a ; TreeNode * cur = root ; TreeNode * pre = NULL ; TreeNode * i = nullptr ; TreeNode * j =

再回首数据结构—AVL树(一)

假如想象 提交于 2020-01-08 04:26:30
前面所讲的二叉搜索树有个比较严重致命的问题就是极端情况下当数据以排序好的顺序创建搜索树此时二叉搜索树将退化为链表结构因此性能也大幅度下降,因此为了解决此问题我们下面要介绍的与二叉搜索树非常类似的结构就诞生了;    AVL(Adelson-Velskii and Landis)树 ,名字取自其发明者 G.M. Adelson-Velsky 和 E.M. Landis的首字母,AVL树是一棵特殊的二叉搜索树它与普通二叉搜索树最主要的区别就是其能够使二叉搜索树维持其左右节点的平衡;    AVL树: 其任意一个节点左子树与右子树高度差不超过1,由于此特征因此需要在AVL增删节点时维护其左右节点使该树满足该特性(左右节点平衡);   此AVL树中节点2节点高度都为2,节点1与3节点高度都为1;节点高度为左右子树中最大的节点高度+1; AVL树实现关键    1、标注其节点高度    2、计算节点平衡因子    3、维护其节点满足左右节点高度不超过1 AVL树的实现   1、AVL树定义   根据AVL树的特性先定义该数据类型的结构; type AVL struct { root *AVLNode size int compare Comparable } type AVLNode struct { e interface{} left *AVLNode right *AVLNode

LeetCode 98 验证二叉搜索树

对着背影说爱祢 提交于 2020-01-07 22:31:31
/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */ int countNodes(struct TreeNode* root){ if(root == NULL) return 0; return 1+countNodes(root->left)+countNodes(root->right); } void inorder(struct TreeNode* root,int *ret,int* returnSize) { if (!root) { return NULL; } inorder(root->left,ret, returnSize); ret[*returnSize] = root->val; (*returnSize)++; inorder(root->right,ret,returnSize); } bool arrayIsSort(int *ret,int num) { for(int i=0;i < num-1;i++) { if (ret[i] >= ret[i+1]) { return false; } } return true; } /*

验证二叉搜索树

浪尽此生 提交于 2020-01-07 13:00:51
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 原题   Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows:   The left subtree of a node contains only nodes with keys less than the node’s key.   The right subtree of a node contains only nodes with keys greater than the node’s key.   Both the left and right subtrees must also be binary search trees. 题目大意   验证二叉搜索树 解题思路   对二叉搜索树进行中序遍历,结果按顺序保存起来,对于二叉搜索树中序遍历其结果有一个从小到大的排列的序列,并且没有重重元素,由此可以判断一棵树是否是二叉搜索树。 代码实现 树结点类 public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } }

二叉搜索树

北战南征 提交于 2020-01-07 12:52:07
二叉搜索树是二叉树的特例,二叉树是树的特例,树是图的特例。 1、二叉搜索树的概念:一个节点的左子节点的关键值小于这个节点的关键值,右子节点的关键值大于或等于这个节点的关键值的二叉树,如上图所示。 参考博客: https://www.jianshu.com/p/16f51b6e0a13 来源: https://www.cnblogs.com/guoyu1/p/12147995.html

图解:二叉搜索树算法(BST)

僤鯓⒐⒋嵵緔 提交于 2020-01-07 12:31:09
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “岁月极美,在于它必然的流逝” “春花 秋月 夏日 冬雪” — 三毛 一、树 & 二叉树 树 是由节点和边构成,储存元素的集合。节点分根节点、父节点和子节点的概念。 如图:树深=4; 5是根节点;同样8与3的关系是父子节点关系。 二叉树binary tree ,则加了“二叉”(binary),意思是在树中作区分。每个节点至多有两个子(child),left child & right child。二叉树在很多例子中使用,比如二叉树表示算术表达式。 如图:1/8是左节点;2/3是右节点; 二、二叉搜索树 BST 顾名思义,二叉树上又加了个搜索的限制。其要求:每个节点比其左子树元素大,比其右子树元素小。 如图:每个节点比它左子树的任意节点大,而且比它右子树的任意节点小 三、BST Java实现 直接上代码,对应代码分享在 Github 主页 BinarySearchTree.java package org.algorithm.tree; /* * Copyright [2015] [Jeff Lee] * * Licensed under the Apache License, Version 2.0 (the