输入一颗二叉树

最近面试里常被问到二叉树相关的题,这类题又往往绕不开二叉树的输入。吃亏了几次后还是决定记录一下。

要构建一颗确定的二叉树,需要给出二叉树的前序+中序/后序+中序的数组,这样可以参考力扣上的两道题:

105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)

106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode) (leetcode-cn.com)

但具体实现思路实在复杂,而且还要求程序员每次构建一棵树前需要自己先得到相应的前序、中序、后序序列。为此,我考虑到从层序遍历的序列入手。以下图为例,由层序遍历的序列nums得到相应的一颗二叉树。其中,节点0对应序列中下标为0,其左孩子节点1对应下标为1(2*0+1),其右孩子节点2对应小标为2(2*0+2);节点1对应序列中的下标为1,其左孩子节点3对应下标为3(2*1+1),其右孩子节点4对应下标为4(2*1+2)...  由数学归纳法可得,层序遍历序列中下标(i)的节点对应的左孩子节点下标为(2*i+1),对应的右孩子节点为(2*i+2)。基于此性质,结合哈希表防止节点的重复构建,代码如下:

输入一颗二叉树

 1 struct TNode{
 2     int m_val;
 3     TNode* left;
 4     TNode* right; 
 5 };
 6 //采用哈希表记录已构建的节点
 7 unordered_map<int, TNode*> m;
 8 int main()
 9 {
10     vector<int> nums = {0, 1, 2, 3, 4, null, null, null ,null, null, null};
11     int n = nums.size();
12     for(int i = 0; i < (n-1)/2; ++i) //父节点的下标不超过(n-1)/2
13     {
14         TNode* root;
15         if(m.find(i) == m.end())
16         {
17             root = new TNode(nums[i]);
18             m.insert({i, root});
19         }
20         else
21             root = m[i];
22 
23         TNode *LNode;
24         int left_index = 2 * i + 1;
25         if(num[left_index] != NULL) //需要先判断左孩子是否存在
26         {
27             if(m.find(left_index) == m.end()) //如果(2*i+1)对应节点未被创建,则创建后放入哈希表中
28             {
29                 LNode = new TNode(nums[left_index]);
30                 m.insert({2*i+1, LNode});
31             }
32             else
33                 LNode = m[left_index]; //如果(2*i+1)对应节点已被创建,则根据下标为key直接获取对应节点
34             root->left = LNode;
35         }
36         else
37             root->left = nullptr;
38 
39         TNode *RNode;
40         int right_index = 2 * i + 2;
41         if(num[right_index] != NULL) //需要先判断右孩子是否存在
42         {
43             if(m.find(right_index) == m.end())
44             {
45                 RNode = new TNode(nums[right_index]);
46                 m.insert({2*i+2, RNode});
47             }
48             else
49                 RNode = m[right_index];
50             root->right = RNode;
51         }
52         else
53             root->right = nullptr;
54     }
55     return m[0]; //哈希表中下标0所对应的节点为根节点
56 }

 

 

上一篇:编写服务器代码,实现收派标准分页查询


下一篇:传入字典的模型项的类型为“System.Data.Entity.DynamicProxies.