二叉搜索树判定
二叉搜索树判定
http://www.nowcoder.com/questionTerminal/e12c53c925754a07b5f5a2a4dd8fa829
题解:
考察点: 递归,二叉树,栈
易错点:
很多同学对于二叉搜索树的概念理解不清,二叉搜索树又被称为二叉排序树,其性质非常简单。首先二叉搜索树,可以为一颗空树,如果不是一颗空树,一定满足如下性质:若左子树非空,则左子树上所有结点均小于它的根结点; 若右子树不空,则右子树上所有结点均大于它的根结点;同时,它的左右子树也分别为二叉搜索树,也就是说不仅仅是根节点满足性质,其任意一个子树同样都满足上述性质。
解法一:中序遍历(递归版)
在易错点中已经说明了二叉搜索树的性质,根据性质,如果有一种办法能先访问它的左子树,再访问它的根节点,最后访问它的右子树,这样的搜索顺序得到的序列一定满足递增的。在二叉树的所有遍历中,中序遍历恰好满足这种性质。于是可以中序遍历二叉树,看其生成的序列是否满足递增性来判断当前二叉树是否为二叉搜索树。
#include <bits/stdc++.h> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; vector<int>res; bool flag=true; void Inorder(TreeNode *root){ if(root==NULL) return; Inorder(root->left); if(res.size()>0){ int len=res.size(); if(res[len-1]>root->val){ flag=false; return; } } res.push_back(root->val); Inorder(root->right); } bool isBinarySearchTree(int n, TreeNode * root) { // do something ! Inorder(root); return flag } int main(void) { int n,r; scanf("%d%d",&n,&r); TreeNode * tree, * root; tree = (TreeNode*)malloc(sizeof(TreeNode)*(n+1)); root = &tree[r]; for (int i=1;i<=n;i++) { int v,l,r; scanf("%d%d%d",&v,&l,&r); tree[i].val = v; tree[i].left = l?&tree[l]:0; tree[i].right = r?&tree[r]:0; } printf(isBinarySearchTree(n,root)?"true\n":"false\n"); return 0; }
解法二:中序遍历(非递归版)
众所周知,的本质是队列,的本质是栈,所以要把递归改成非递归当让是要使用栈了。栈是一种先进后出的数据结构,先进入栈中的元素,最后从栈中出来。基于这种思想,对于每一颗子树都需要将左子树不断压栈,直到找到最左边的结点,然后再进行出栈操作,对于每一个结点的出栈,先比较和前面已出栈结点是否构成升序,然后将其指向其右指针,这样可以保证是按照中序遍历顺序出栈的。
#include <bits/stdc++.h> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; bool isBinarySearchTree(int n, TreeNode * root) { // do something ! int mi=INT_MIN; stack<TreeNode*>s; while(!s.empty()||root){ while(root){ s.push(root); root=root->left; } root=s.top(); s.pop(); if(root->val<=mi) return false; mi=root->val; root=root->right; } return true; } int main(void) { int n,r; scanf("%d%d",&n,&r); TreeNode * tree, * root; tree = (TreeNode*)malloc(sizeof(TreeNode)*(n+1)); root = &tree[r]; for (int i=1;i<=n;i++) { int v,l,r; scanf("%d%d%d",&v,&l,&r); tree[i].val = v; tree[i].left = l?&tree[l]:0; tree[i].right = r?&tree[r]:0; } printf(isBinarySearchTree(n,root)?"true\n":"false\n"); return 0; }