遍历重构

  1. 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
  2. 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。
  3. 把一个有序整数数组放到一棵二叉树中,要求树的高度最小。

1、思路:

  前序遍历的第一个是根结点,在中序遍历中找到该结点,则该结点左侧是左子树的范围,右侧是右子树的范围。由该范围再去前序遍历数组中圈定同样个数的左右子树。同理递归处理左右子树。

Construct
 1 BinaryTreeNode* Construct(int* preorder, int* inorder, int length)
 2 {
 3     if(preorder == NULL || inorder == NULL || length <= 0)
 4         return NULL;
 5 
 6     return ConstructCore(preorder, preorder + length - 1,
 7         inorder, inorder + length - 1);
 8 }
 9 
10 BinaryTreeNode* ConstructCore
11 (
12     int* startPreorder, int* endPreorder, 
13     int* startInorder, int* endInorder
14 )
15 {
16     // 前序遍历序列的第一个数字是根结点的值
17     int rootValue = startPreorder[0];
18     BinaryTreeNode* root = new BinaryTreeNode();
19     root->m_nValue = rootValue;
20     root->m_pLeft = root->m_pRight = NULL;
21 
22     if(startPreorder == endPreorder)
23     {
24         if(startInorder == endInorder && *startPreorder == *startInorder)
25             return root;
26         else
27             throw std::exception("Invalid input.");
28     }
29 
30     // 在中序遍历中找到根结点的值
31     int* rootInorder = startInorder;
32     while(rootInorder <= endInorder && *rootInorder != rootValue)
33         ++ rootInorder;
34 
35     if(rootInorder == endInorder && *rootInorder != rootValue)
36         throw std::exception("Invalid input.");
37 
38     int leftLength = rootInorder - startInorder;
39     int* leftPreorderEnd = startPreorder + leftLength;
40     if(leftLength > 0)
41     {
42         // 构建左子树
43         root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd, 
44             startInorder, rootInorder - 1);
45     }
46     if(leftLength < endPreorder - startPreorder)
47     {
48         // 构建右子树
49         root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder,
50             rootInorder + 1, endInorder);
51     }
52 
53     return root;
54 }

 

2、思路:

  二叉搜索树的特点是左子树的所有元素比根节点小,右子树的所有元素比根节点大。由根节点找到左右子树的范围,并判断是否负责大小性质。

VerifySquenceOfBST
 1 bool VerifySquenceOfBST(int sequence[], int length)
 2 {
 3     if(sequence == NULL || length <= 0)
 4         return false;
 5 
 6     int root = sequence[length - 1];
 7 
 8     // 在二叉搜索树中左子树的结点小于根结点
 9     int i = 0;
10     for(; i < length - 1; ++ i)
11     {
12         if(sequence[i] > root)
13             break;
14     }
15 
16     // 在二叉搜索树中右子树的结点大于根结点
17     int j = i;
18     for(; j < length - 1; ++ j)
19     {
20         if(sequence[j] < root)
21             return false;
22     }
23 
24     // 判断左子树是不是二叉搜索树
25     bool left = true;
26     if(i > 0)
27         left = VerifySquenceOfBST(sequence, i);
28 
29     // 判断右子树是不是二叉搜索树
30     bool right = true;
31     if(i < length - 1)
32         right = VerifySquenceOfBST(sequence + i, length - i - 1);
33 
34     return (left && right);
35 }

 

3、思路:

  递归对半处理数组,每次取中间节点作为root,左半部分和右半部分分别作为左右孩子。

 1 TreeNode* Array2TreeCore(int data[], int start, int end)
 2 {
 3     if (start > end) return NULL;
 4     int mid = (start + end) / 2;
 5     TreeNode* root = new TreeNode(data[mid]);
 6     root->left = Array2TreeCore(data, start, mid - 1);
 7     root->right = Array2TreeCore(data, mid + 1, end);
 8     return root;
 9 }
10 
11 TreeNode* Array2Tree(int data[], int len)
12 {
13     if (data == NULL || len < 0) return NULL;
14     return Array2TreeCore(data, 0, len - 1);
15 }
Array2Tree

 

posted on 2013-04-14 21:59  月moon鸟  阅读(213)  评论(0编辑  收藏  举报

导航