二叉排序树之递归陷阱
来源:互联网 发布:网络推广的手段有哪些 编辑:程序博客网 时间:2024/03/28 23:12
判是否是二叉排序树,看似想到递归来判,因为二叉树之类的都是递归定义,判定递归自然很好理解,结果发现挂了
if(root==NULL) return true; if(root->left==NULL&&root->right!=NULL) return (root->val<root->right->val) && isValidBST(root->left) && isValidBST(root->right); if(root->right==NULL&&root->left!=NULL) return (root->left->val<root->val) && isValidBST(root->left) && isValidBST(root->right); if(root->left==NULL&&root->right==NULL) return true; return (root->left->val<root->val) && (root->val<root->right->val) && isValidBST(root->left) && isValidBST(root->right);
结果挂了,想不通,之前左右子树空的几种组合情况还没考虑,因为后面还有left right 访问val的语句。后来再看一遍定义,懂了。
虽说他是递归定义的,但是它是指整个左子树都小于根,整个右子树都大于根,如果只是左孩子右孩子小于大于根上面递归是没有问题的,但是现在不行,例如上述语句会把左孩子虽然是二叉排序树,但是有一个最大的比根大的二叉树包含进来,也即r->left->val< r->val, r->left->val< r->left最右下->val 这两句退不出 r->left最右下->val <r->val
简单说就是a<b, a<c 不能确定b c的关系,而这种如果出现非二叉排序树,上面代码已然判为true,于是仔细看定义发现问题了。
只能乖乖中序遍历,然后看是否单调递增排序,还不能非递减,因为定义是严格小于 大于
附上代码:
bool isValidBST(TreeNode *root) { if(root==NULL) return true; stack<TreeNode* > S; //S.push(root); TreeNode* p=root; vector<int> order; while(!S.empty()||p!=NULL) { while(p!=NULL) { S.push(p); p=p->left; } p=S.top(); S.pop(); order.push_back(p->val); p=p->right; //if(S->right!=NULL) // S.push(S->right); //if(S->left!=NULL) // S.push(S->left); } for(int i=0;i<order.size()-1;i++) { if(order.at(i)>=order.at(i+1)) return false; } return true; /* if(root==NULL) return true; if(root->left==NULL&&root->right!=NULL) return (root->val<root->right->val) && isValidBST(root->left) && isValidBST(root->right); if(root->right==NULL&&root->left!=NULL) return (root->left->val<root->val) && isValidBST(root->left) && isValidBST(root->right); if(root->left==NULL&&root->right==NULL) return true; return (root->left->val<root->val) && (root->val<root->right->val) && isValidBST(root->left) && isValidBST(root->right); */ }
另外还有一道回文串,一开始学程舍就接触过的,这次不考虑非数字字母的字符,里面还是有越界判断又忘了,另外急于提交,连逻辑判断语句都写错了= =
bool isPalindrome(string s) { int lefti=0,righti=s.length()-1; while(lefti<righti) { while(lefti<righti &&!((s[lefti]<='z'&&s[lefti]>='a')||(s[lefti]<='Z'&&s[lefti]>='A')||(s[lefti]<='9'&&s[lefti]>='0'))) lefti++;if(lefti==righti) return true; while(righti>lefti &&!((s[righti]<='z'&&s[righti]>='a')||(s[righti]<='Z'&&s[righti]>='A')||(s[righti]<='9'&&s[righti]>='0'))) righti--;if(lefti==righti) return true; if(s[lefti]==s[righti]||s[lefti]+'A'-'a'==s[righti]||s[righti]+'A'-'a'==s[lefti]) { lefti++; righti--; } else { return false; } } return true; }
另外看到了里面lefti<righti 让我想到了让人不寒而栗的Hoarn版partition函数= =
今天偶然看到博客分析二叉树的性质,因为扩展到图的时候还是比较有用的。
1. ni 表示度数(孩子数)为i的结点个数,n为总结点数,m为边数或总度数
n2+n1+n0=n=m+1
2n2+n1=m
两式一减 n2-n0=-1 n0=n2+1
所以二叉树的叶子结点(终端结点,度为0的结点) 与度为2的结点的个数总是差一
2 i层有2^(i-1) 个结点
3 n个结点二叉树有 上界(log2(n+1)) 或下届(log2n)+1高度
4 高度为h的二叉树做多2^h-1个结点
http://blog.csdn.net/ab198604/article/details/8491370
5 有n+1 个空指针域 n个结点,m个边,m=n-1 共2n个指针域 所以剩n+1个指针域,这些域也是用来建线索二叉树,尽管想到那个繁琐的东西就头大= =
- 二叉排序树之递归陷阱
- 递归陷阱
- 递归的陷阱
- 构建二叉排序树(非递归)
- 数据结构面试之六——二叉树的常见操作2(非递归遍历&二叉排序树)
- 数据结构面试之六——二叉树的常见操作2(非递归遍历&二叉排序树)
- 数据结构面试之六——二叉树的常见操作2(非递归遍历&二叉排序树)
- 动态查找之二叉排序树
- 数据结构之二叉排序树
- 二叉排序树之删除节点
- 数据结构之(二叉排序树)
- 数据结构学习之二叉排序树
- 查找系列之二叉排序树
- 数据结构之二叉排序树
- 数据结构之二叉排序树
- 二叉排序树之删除操作
- 数据结构之二叉排序树
- 数据结构之二叉排序树
- JDK的卸载、安装与配置
- Maven nexus 安装nexus : wrapper | OpenSCManager failed - 拒绝访问。 (0x5)
- DataGridView导出excel
- 输入一个链表的头结点,从尾到头反过来输出每个结点的值
- linux 文本显示和处理命令
- 二叉排序树之递归陷阱
- html第3.4.五章超文本链接
- ASP.NET MVC 过滤器(四)
- bzoj3401[Usaco2009 Mar]Look Up 仰望
- 在Centos上安装与配置Tomcat
- Spring缓存简单介绍(Spring Cache)
- uva 10795 - A Different Task (递归+状态转移)
- SRM 622 D2L3: Subsets, math, backtrack
- python的诗歌实战项目