二叉排序树之递归陷阱

来源:互联网 发布:网络推广的手段有哪些 编辑:程序博客网 时间: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个指针域,这些域也是用来建线索二叉树,尽管想到那个繁琐的东西就头大= =

0 0
原创粉丝点击