对于一颗搜索二叉树,最简单的方法就是用中序遍历,看是不是一个递增数列,如果是则是一颗搜索二叉树,如果不是则不是搜索二叉树。在这里用一个lastVisit去记录上一次搜索到的节点。整个过程就是先找到最左下角的节点,更新这个lastVisit为这个节点的值,然后按照中序遍历依次更新即可。代码如下。
1 #include <stdio.h> 2 #include <climits> 3 4 //二叉树结点 5 typedef struct binary_tree_node_t{ 6 binary_tree_node_t * left; 7 binary_tree_node_t * right; 8 int elem; 9 10 }; 11 12 //如果是BST, 其中序遍历应该是从小到大的顺序 13 int lastVisit = INT_MIN; 14 15 int judge_BST(binary_tree_node_t * root){ 16 if(root == NULL){ 17 return 1; 18 } 19 20 int judgeLeft = judge_BST(root->left);//先判断左子树 21 22 if( (root->elem >= lastVisit) && judgeLeft == 1){//当前结点比上次访问的数值要大 23 lastVisit = root->elem; 24 }else{ 25 return 0; 26 } 27 28 int judgeRight = judge_BST(root->right);//最后右子树 29 30 return judgeRight; 31 32 } 33 34 35 //判断一颗二叉树是不是二叉排序树 36 int main(){ 37 binary_tree_node_t ns[10]; 38 39 for(int i = 1; i <= 6; i++){ 40 binary_tree_node_t tmp; 41 tmp.elem = i; 42 tmp.left = NULL;//必须显式初始化为NULL 43 tmp.right = NULL; 44 ns[i] = tmp; 45 } 46 47 binary_tree_node_t root; 48 root.elem = 4; 49 50 root.left = &ns[2]; 51 root.right = &ns[5]; 52 53 ns[2].left = &ns[1]; 54 ns[2].right = &ns[3]; 55 56 ns[5].right = &ns[6]; 57 58 59 printf("%d\n", judge_BST(&root)); 60 61 return 0; 62 }
对于一颗完全二叉树采用广度优先遍历,从根节点开始,入队列,如果队列不为空,循环。遇到第一个没有左儿子或者右儿子的节点,设置标志位,如果之后再遇到有左/右儿子的节点,那么这不是一颗完全二叉树。这个方法需要遍历整棵树,复杂度为O(N),N为节点的总数。
1 //二叉树结点定义 2 typedef struct Node 3 { 4 int data; 5 struct Node* left; 6 struct Node* right; 7 }Node; 8 9 //实现广度遍历需要队列 10 Queue<Node*> queue; 11 12 //第n层最右节点标志 13 bool leftMost = false; 14 15 bool ProcessChild(Node* child) 16 { 17 if (child) 18 { 19 if (!leftMost) 20 { 21 queue.push(child); 22 } 23 else 24 { 25 return false; 26 } 27 } 28 else 29 { 30 leftMost = true; 31 } 32 33 return true; 34 } 35 36 bool IsCompleteBinaryTree(Node* root) 37 { 38 //空树也是完全二叉树 39 if (!root) 40 return true; 41 42 //首先根节点入队列 43 queue.push(root); 44 45 while(!queue.empty()) 46 { 47 Node* node = queue.pop(); 48 49 //处理左节点 50 if (!ProcessChild(node->left)) 51 return false; 52 53 //处理右节点 54 if (!ProcessChild(node->right)) 55 return false; 56 } 57 58 //广度优先遍历完毕,此乃完全二叉树 59 return true; 60 }