怎样判断一个二叉树是binary search tree
怎么实现 boolean isBST(Node *root)?
看看这个,简单明了
http://www.ardendertat.com/2011/10/10/programming-interview-questions-7-binary-search-tree-check/
In-order traverse能够按顺序打印BST的,所以只需要按照in-order traverse
走一遍,同时记录last visited node value,保证当前node的值比最后一个大
就是BST了。
Programming Interview Questions 7: Binary Search Tree Check
Posted on October 10, 2011 by Arden
This is a very common interview question. Given a binary tree, check whether it’s a binary search tree or not. Simple as that..
class Node:
def __init__(self, val=None):
self.left, self.right, self.val = None, None, val
INFINITY = float("infinity")
NEG_INFINITY = float("-infinity")
def isBST(tree, minVal=NEG_INFINITY, maxVal=INFINITY):
if tree is None:
return True
if not minVal <= tree.val <= maxVal:
return False
return isBST(tree.left, minVal, tree.val) and \
isBST(tree.right, tree.val, maxVal)
There’s an equally good alternative solution. If a tree is a binary search tree, then traversing the tree inorder should lead to sorted order of the values in the tree. So, we can perform an inorder traversal and check whether the node values are sorted or not. Here is the code:
def isBST2(tree, lastNode=[NEG_INFINITY]):
if tree is None:
return True
if not isBST2(tree.left, lastNode):
return False
if tree.val < lastNode[0]:
return False
lastNode[0]=tree.val
return isBST2(tree.right, lastNode)
I personally like this question a lot because it’s simple (but not trivial) and demonstrates the basic knowledge of binary search trees and tree traversals.
As for the in order traversal above: where are you adding to the node list?
A special note about these types of problems when interviewing at Microsoft: while algorithmically your solution should be recursive, your implementation should be prefixed by: “the problem with the recursive implementation is that it’s only good when you know the depth, otherwise you can easily blow the stack”. This shows you understand the practical difference between writing code in a classroom and in a production environment. If the interviewer then says: “let’s say you don’t need to worry about that”, you proceed with your solution, but twice in my own experience the problem was precisely about whether I would just rush to implement the obvious and well known book solution, or stop to consider the real world implications.
You’re right about recursion and stack space. I didn’t mention that because both of the algorithms are recursive. If we would like to code it iteratively, than we have to maintain a queue, which will use the heap space. But as you said, it’s definitely useful to first step back and thoroughly analyze all the possible solutions with their real world implications, and then start coding the actual algorithm.
There’s no reason to build a list of all node values in isBST2. You only need the value of the last node visited so far. Rename nodes to maxValBox and update it like this:
maxValBox[0] = tree.val
怎么实现 boolean isBST(Node *root)?
看看这个,简单明了
http://www.ardendertat.com/2011/10/10/programming-interview-questions-7-binary-search-tree-check/
In-order traverse能够按顺序打印BST的,所以只需要按照in-order traverse
走一遍,同时记录last visited node value,保证当前node的值比最后一个大
就是BST了。
Programming Interview Questions 7: Binary Search Tree Check
Posted on October 10, 2011 by Arden
This is a very common interview question. Given a binary tree, check whether it’s a binary search tree or not. Simple as that..
The first solution that comes to mind is, at every node check whether its value is larger than or equal to its left child and smaller than or equal to its right child (assuming equals can appear at either left or right). However, this approach is erroneous because it doesn’t check whether a node violates any condition with its grandparent or any of its ancestors. The following tree would be incorrectly classified as a binary search tree, the algorithm won’t be able to detect the inconsistency between 3 and 4:
3
/ \
2 5
/\
1 4
class Node:
def __init__(self, val=None):
self.left, self.right, self.val = None, None, val
INFINITY = float("infinity")
NEG_INFINITY = float("-infinity")
def isBST(tree, minVal=NEG_INFINITY, maxVal=INFINITY):
if tree is None:
return True
if not minVal <= tree.val <= maxVal:
return False
return isBST(tree.left, minVal, tree.val) and \
isBST(tree.right, tree.val, maxVal)
There’s an equally good alternative solution. If a tree is a binary search tree, then traversing the tree inorder should lead to sorted order of the values in the tree. So, we can perform an inorder traversal and check whether the node values are sorted or not. Here is the code:
def isBST2(tree, lastNode=[NEG_INFINITY]):
if tree is None:
return True
if not isBST2(tree.left, lastNode):
return False
if tree.val < lastNode[0]:
return False
lastNode[0]=tree.val
return isBST2(tree.right, lastNode)
I personally like this question a lot because it’s simple (but not trivial) and demonstrates the basic knowledge of binary search trees and tree traversals.
As for the in order traversal above: where are you adding to the node list?
A special note about these types of problems when interviewing at Microsoft: while algorithmically your solution should be recursive, your implementation should be prefixed by: “the problem with the recursive implementation is that it’s only good when you know the depth, otherwise you can easily blow the stack”. This shows you understand the practical difference between writing code in a classroom and in a production environment. If the interviewer then says: “let’s say you don’t need to worry about that”, you proceed with your solution, but twice in my own experience the problem was precisely about whether I would just rush to implement the obvious and well known book solution, or stop to consider the real world implications.
You’re right about recursion and stack space. I didn’t mention that because both of the algorithms are recursive. If we would like to code it iteratively, than we have to maintain a queue, which will use the heap space. But as you said, it’s definitely useful to first step back and thoroughly analyze all the possible solutions with their real world implications, and then start coding the actual algorithm.
There’s no reason to build a list of all node values in isBST2. You only need the value of the last node visited so far. Rename nodes to maxValBox and update it like this:
maxValBox[0] = tree.val