Note: Transfer from http://blog.csdn.net/sgbfblog/article/details/7771096

Determine if a tree is two forks search tree: (1) Question:

Given a binary tree, determine if the two-fork tree is a two-fork search tree.

(2) Analysis:

First explain the difference between a binary tree and a two-fork search tree. A binary tree refers to a tree structure with a maximum of 2 children per node; a binary search tree is a binary tree, but it has additional constraints that must be set for each node:

Node node's left subtree all nodes are less than the value of node.

All nodes in the right subtree of node node have values greater than node values.

The left and right sub-tree of node node must also be a two-fork search tree.

This question may often be asked in an interview about the understanding of the definition of a two-fork search tree. At first glance at this question, you may want to achieve this:

(3) Solution 1: Brute Force search

(3.1) Analysis:

Assume that the current node value is K. For each node in the binary tree, determine whether the left child's value is less than k, and whether the right child's value is greater than K. If all nodes satisfy this condition, then the two fork tree is a binary search tree.

Unfortunately, this algorithm is wrong. Consider the following two-fork tree, which conforms to the criteria of the above algorithm, but it is not a binary search tree.

10

/ \

5--------Binary tree (1)

/ \

6 20

Then, according to the definition of binary search tree, can think of a violent search method to determine whether the binary tree is a two-fork search tree.

Assume that the current node value is K. For each node in the binary tree, the values of all the nodes in the left subtree must be less than k, and the values of all nodes in the right subtree must be greater than K.

Brute Force search algorithm code is as follows, although inefficient, but it can do the job. The worst case complexity of the solution is O (n^2), and N is the number of nodes. (Worst case scenario when all nodes are on one side)

(3.2) Code implementation 1:

/* Determine if the node value of the left subtree is less than val*/

BOOL Issubtreelessthan (BinaryTree *p, int val)

{

if (!p) return true;

Return (P->data < Val &&

Issubtreelessthan (P->left, Val) &&

Issubtreelessthan (P->right, Val));

}

/* Determine if the node value of the right subtree is greater than val*/

BOOL Issubtreegreaterthan (BinaryTree *p, int val)

{

if (!p) return true;

Return (P->data > Val &&

Issubtreegreaterthan (P->left, Val) &&

Issubtreegreaterthan (P->right, Val));

}

/* Determine if the binary tree is a two-fork search tree */

BOOL Isbstbruteforce (BinaryTree *p)

{

if (!p) return true;

Return Issubtreelessthan (P->left, P->data) &&

Issubtreegreaterthan (P->right, P->data) &&

Isbstbruteforce (P->left) &&

Isbstbruteforce (P->right);

}

(3.3) Code implementation 2:

A similar solution is: for node node, determine whether the maximum value of the left subtree is greater than the value of node, if so, then the two fork tree is not a binary search tree. If not, then determine if the right subtree minimum is less than or equal to the value of node.

If it is, it is not a binary search tree. If not then recursively determine whether the left and right sub-tree is a two-fork search tree.

(The function of the MaxValue and MinValue functions in the code is to return the maximum and minimum values in the binary tree, assuming that the binary tree is a two-fork search tree, the actual return is not necessarily the maximum value and the minimum value);

Note: The algorithm should be a counter-method, that is, the hypothesis is a two-fork search tree, you need to meet the characteristics of binary search tree, the possibility of excluding non-conforming is binary search tree;

int Isbst (struct node* node)

{

if (Node==null) return (true);

Returns False if the left dial hand tree maximum >= The value of the current node

if (Node->left!=null && maxValue (node->left) >= node->data)

return (false);

Returns False if the right subtree minimum value <= The value of the current node

if (Node->right!=null && minValue (node->right) <= node->data)

return (false);

Returns False if the Zuozi or right subtree is not BST

if (!isbst (node->left) | |!isbst (node->right))

return (false);

Pass all tests, return True

return (true);

}

int maxValue (struct node* node)

{

STURCT node* pnode = node;

int maxData = pnode->data;

while (Pnode) {

if (pnode->right) {

MaxData = pnode->right->data;

}

}

return maxData;

}

(4) Solution 2: A better solution

(4.1) Analysis:

As an example of the binary tree (1) mentioned earlier, when we start from the node 10 times to the right node 15 o'clock, we know that the right subtree node value must be between 10 and +infinity (Infinity). When we traverse to the left child node of node 15 6 o'clock,

We know that the left sub-tree node value of node 15 must be between 10 and 15. Obviously, node 6 is not eligible, so it is not a binary search tree.

(4.2) The algorithm code is as follows:

int isBST2 (struct node* node)

{

Return (Isbstutil (node, int_min, Int_max));

}

/*

The given two-fork tree is BST and returns True, and its value is >min and < Max.

*/

int isbstutil (struct node* node, int min, int max)

{

if (Node==null) return (true);

returns False if Min and max constraints are not met

if (Node->data<=min | | node->data>=max) return (false);

Recursive determination of whether the left and right sub-trees satisfy min and max constraints

Return

Isbstutil (node->left, Min, node->data) &&

Isbstutil (Node->right, Node->data, Max)

);

}

Since the algorithm only needs to access each node 1 times, the time complexity is O (n), which is much more efficient than solution 1.

(5) Middle sequence traversal algorithm:

(5.1) Analysis:

Because a binary search tree after the middle sequence of its node value is from small to large order, so given the following solution.

(5.2) Code Implementation 1:

According to the middle sequence traversal binary search tree, the resulting sequence has an ordered sequence, saved to the array, then an ordered array;

Then, according to whether the obtained array is an ordered array, to determine whether a binary tree is ordered;

int a[100] = {-1};

int count = 0;

O (NLG (n))

void Bst_mid_traverse (struct node* root)

{

Bst_mid_traverse (Root->left);

if (root) {

a[count++] = root->data;

}

else {

return;

}

Bst_mid_traverse (Root->right);

}

O (N)

int Is_sort_array (int*a, int len)

{

int is_desc = (a[0] >= a[len-1])? 1:0;

if (IS_DESC) {

for (int i = 0; i < len-1 && A[i] > = a[i+1]; i++) {

//

}

}

else {

for (int i = 0; i < len-1 && A[i] < = a[i+1]; i++) {

//

}

}

if (I < len-1) {

return 0;

}

else {

return 1;

}

}

(5.3) Code implementation 2:

BOOL Isbstinorder (BinaryTree *root)

{

int prev = int_min;

return Isbstinorderhelper (root, prev);

}

/* This function determines whether the binary tree p is a binary search tree, and its node value is greater than prev*/.

BOOL Isbstinorderhelper (BinaryTree *p, int& prev)

{

if (!p) return true;

if (Isbstinorderhelper (P->left, prev)) {//If Zuozi is a two-fork search tree with a node value greater than prev

if (P->data > Prev) {//Determines whether the current node value is greater than prev because the Prev has been set to the maximum value of the node that has been traversed in the middle order.

Prev = p->data;

Return Isbstinorderhelper (P->right, prev); If the node value is greater than Prev, set prev as the current node value and determine if the right subtree is a binary search tree and the node value is greater than prev.

} else {

return false;

}

}

else {

return false;

}

}