二叉树题目总结(一)

1. 线索化二叉树

一颗有n个节点的二叉树,必然有n + 1个空指针,可以利用这些空指针记录二叉树的某种遍历序的前驱和(或)后继信息

下面给出中序线索化二叉树的代码:

 1 #include <iostream>
 2
 3 struct ThreadTreeNode {
 4     int val;
 5     bool ltag; /* 0 for link, 1 for thread */
 6     bool rtag;
 7     ThreadTreeNode *left;
 8     ThreadTreeNode *right;
 9     ThreadTreeNode(int v = -1) : val(v), ltag(0), rtag(0), left(NULL), right(NULL) { }
10 };
11
12 class Solution {
13 public:
14     void *inorderThreadMirror(ThreadTreeNode *root) {
15         if(!root) return NULL;
16         ThreadTreeNode *prev = NULL;
17         ThreadTreeNode *curr = root;
18         while(curr) {
19             if(!curr->left) {
20                 curr->ltag = 1; /* no left child threaded it */
21                 curr->left = prev; /* if curr is the first node in inorder, its prev is NULL */
22                 prev = curr;
23                 curr = curr->right;
24             }
25             else {
26                 ThreadTreeNode *temp = curr->left;
27                 while(temp->right && temp->right != curr) temp = temp->right;
28                 if(!temp->right) { /* has not been visited */
29                     temp->rtag = 1;
30                     temp->right = curr;
31                     curr = curr->left;
32                 }
33                 else { /* has been visited */
34                     prev = curr;
35                     curr = curr->right;
36                 }
37             }
38         }
39     }
40     void inorderTraversal(ThreadTreeNode *root) {
41         while(root && root->ltag != 1) root = root->left; /* find the first node in inorder */
42         while(root) {
43             std::cout << root->val << "  ";
44             if(!root->right) break; /* right node in NULL, says that its the last node */
45             if(root->rtag == 1) /* thread */
46                 root = root->right;
47             else { /* link */
48                 root = root->right;
49                 while(root && root->ltag != 1) root = root->left;
50             }
51         }
52         std::cout << std::endl;
53     }
54 };
55
56 int main() {
57     ThreadTreeNode *root = new ThreadTreeNode(0);
58     root->left = new ThreadTreeNode(1);
59     root->right = new ThreadTreeNode(2);
60     root->left->left = new ThreadTreeNode(3);
61     root->left->right = new ThreadTreeNode(4);
62     root->left->right->left = new ThreadTreeNode(5);
63     root->left->right->right = new ThreadTreeNode(6);
64     Solution s;
65     s.inorderThreadMirror(root);
66     s.inorderTraversal(root);
67     return 0;
68 }

2. 求二叉树节点间的最大距离

对任一个节点,计算该节点到左边的最大距离+到右边的最大距离,保存起来,但只返回到左边或到右边的最大距离

 1 #include <iostream>
 2
 3 struct TreeNode {
 4     int val;
 5     TreeNode *left;
 6     TreeNode *right;
 7     TreeNode(int v = -1) : val(v), left(NULL), right(NULL) { }
 8 };
 9
10 class Solution {
11 public:
12     Solution() {r_max = 0;}
13
14     int maxDistanceDFS(TreeNode *root) {
15         dfs(root);
16         return r_max;
17     }
18     int maxDistance(TreeNode *root) {
19         if(!root) return 0;
20         int a = maxDep(root->left) + maxDep(root->right);
21         int b = maxDistance(root->left);
22         int c = maxDistance(root->right);
23         return std::max(std::max(a, b), c);
24     }
25     int r_max;
26 private:
27     int maxDep(TreeNode *root) {
28         if(!root) return 0;
29         return std::max(maxDep(root->left), maxDep(root->right)) + 1;
30     }
31     int dfs(TreeNode *root) {
32         if(!root) return 0;
33         int l = dfs(root->left);
34         int r = dfs(root->right);
35         r_max = std::max(r_max, l + r);
36         return l > r ? l + 1 : r + 1;
37     }
38 };
39
40 int main() {
41     TreeNode *root = new TreeNode(1);
42     root->right = new TreeNode(3);
43     root->right->left = new TreeNode(4);
44     root->right->right = new TreeNode(5);
45     root->right->left->left = new TreeNode(6);
46     root->right->left->right = new TreeNode(7);
47     root->right->right->right = new TreeNode(8);
48     std::cout << (new Solution)->maxDistanceDFS(root) << std::endl;
49     std::cout << (new Solution)->maxDistance(root) << std::endl;
50     return 0;
51 }

3. 最近公共祖先

 1 #include <iostream>
 2
 3 struct TreeNode {
 4     int val;
 5     TreeNode *left;
 6     TreeNode *right;
 7     TreeNode(int v = -1) : val(v), left(NULL), right(NULL) { }
 8 };
 9
10 class Solution {
11 public:
12     TreeNode *commonForefather(TreeNode *root, TreeNode *childa, TreeNode *childb) {
13         if(isHere(root->left, childa) && isHere(root->left, childb)) {
14             if(root->left == childa || root->left == childb)
15                 return root;
16             return commonForefather(root->left, childa, childb);
17         }
18         else if(isHere(root->right, childa) && isHere(root->right, childb)) {
19             if(root->right == childa || root->right == childb)
20                 return root;
21             return commonForefather(root->right, childa, childb);
22         }
23         else
24             return root;
25     }
26 private:
27     bool isHere(TreeNode *root, TreeNode *child) {
28         if(root == child)
29             return true;
30         if(root == NULL)
31             return false;
32         return isHere(root->left, child) || isHere(root->right, child);
33     }
34 };
35
36 int main() {
37     TreeNode *root = new TreeNode(1);
38     root->left = new TreeNode(2);
39     root->right = new TreeNode(3);
40     root->right->left = new TreeNode(4);
41     root->right->left->left = new TreeNode(5);
42     root->right->left->right = new TreeNode(6);
43     std::cout << (new Solution)->commonForefather(root, root->right->left->left, root->right->left)->val << std::endl;
44     return 0;
45 }

4. 二叉树的高度和宽度

高度定义为二叉树的最大深度

宽度定义为高度相同节点数目的最大值

 1 #include <iostream>
 2 #include <queue>
 3
 4 struct TreeNode{
 5     int val;
 6     TreeNode *left;
 7     TreeNode *right;
 8     TreeNode(int v = -1) : val(v), left(NULL), right(NULL) { }
 9 };
10
11 class Solution {
12 public:
13     int biTreeDep(TreeNode *root) {
14         if(!root) return 0;
15         return std::max(biTreeDep(root->left), biTreeDep(root->right)) + 1;
16     }
17     int biTreeWidth(TreeNode *root) {
18         if(!root) return 0;
19         std::queue<TreeNode *> que;
20         int maxWidth = 0;
21         int curWidth = 0;
22         que.push(root);
23         que.push(NULL);
24         while(!que.empty()) {
25             while(que.front()) {
26                 TreeNode *curr = que.front();
27                 que.pop();
28                 curWidth++;
29                 if(curr->left) que.push(curr->left);
30                 if(curr->right) que.push(curr->right);
31             }
32             maxWidth = std::max(maxWidth, curWidth);
33             curWidth = 0;
34             que.pop();
35             if(que.empty()) break;
36             que.push(NULL);
37         }
38         return maxWidth;
39     }
40 };
41
42 int main() {
43     TreeNode *root = new TreeNode(1);
44     root->left = new TreeNode(2);
45     root->right = new TreeNode(3);
46     root->right->right = new TreeNode(4);
47     root->right->right->left = new TreeNode(5);
48     root->right->right->left->right = new TreeNode(6);
49     Solution s;
50     std::cout << s.biTreeDep(root) << std::endl;
51     std::cout << s.biTreeWidth(root) << std::endl;
52     return 0;
53 }

5. Huffman编码

 1 #include <iostream>
 2 #include <vector>
 3 #include <queue>
 4 #include <map>
 5 using namespace std;
 6
 7 typedef unsigned int uint;
 8 struct HuffTreeNode {
 9     uint weight;
10     HuffTreeNode *lchild;
11     HuffTreeNode *rchild;
12     HuffTreeNode *parent;
13     HuffTreeNode(uint w = 0) : weight(w), lchild(NULL), rchild(NULL), parent(NULL) { }
14 };
15 struct Cmp {
16     bool operator() (const HuffTreeNode *a, const HuffTreeNode *b) {
17         return a->weight > b->weight;
18     }
19 };
20 class Solution {
21 public:
22     HuffTreeNode* createHuffmanCodingTree(const vector<uint> &weight) {
23         priority_queue<HuffTreeNode *, vector<HuffTreeNode *>, Cmp > pri_que;
24         HuffTreeNode *prev = NULL;
25         HuffTreeNode *curr = NULL;
26         for(int i = 0; i < weight.size(); i++)
27             pri_que.push(new HuffTreeNode(weight[i]));
28         while(!pri_que.empty()) {
29             prev = pri_que.top(), pri_que.pop();
30             if(pri_que.empty()) break;
31             curr = pri_que.top(), pri_que.pop();
32             HuffTreeNode *parent = new HuffTreeNode(prev->weight + curr->weight);
33             parent->lchild = prev->lchild ? curr : prev;
34             parent->rchild = prev->lchild ? prev : curr;
35             prev->parent = curr->parent = parent;
36             pri_que.push(parent);
37         }
38         this->root = prev;
39         return prev;
40     }
41     void createHuffmanEncodeMap() {
42         string bits;
43         HuffTreeNode *curr = this->root;
44         while(curr) {
45             if(!curr->lchild) {
46                 encode_map[curr->weight] = bits;
47                 curr = curr->rchild;
48             }
49             else {
50                 HuffTreeNode *temp = curr->lchild;
51                 int backlevel = 1;
52                 while(temp->rchild && temp->rchild != curr) temp = temp->rchild, backlevel++;
53                 if(!temp->rchild) {
54                     /* visit curr */
55                     bits += "0";
56                     temp->rchild = curr;
57                     curr = curr->lchild;
58                 }
59                 else {
60                     /* trace back to "root" node */
61                     bits = bits.substr(0, bits.size() - backlevel);
62                     bits += "1";
63                     temp->rchild = NULL;
64                     curr = curr->rchild;
65                 }
66             }
67         }
68     }
69 private:
70     map<uint, string> encode_map;
71     map<string, uint> decode_map;
72     HuffTreeNode *root;
73 };
74
75 int main(int argc, char **argv) {
76     vector<uint> v_ui;
77     v_ui.push_back(5);
78     v_ui.push_back(29);
79     v_ui.push_back(7);
80     v_ui.push_back(8);
81     v_ui.push_back(14);
82     v_ui.push_back(23);
83     v_ui.push_back(3);
84     v_ui.push_back(11);
85     Solution s;
86     s.createHuffmanCodingTree(v_ui);
87     s.createHuffmanEncodeMap();
88     for(int i = 0; i < v_ui.size(); i++)
89         cout << v_ui[i] << " : " << s.encode_map[v_ui[i]] << endl;
90     return 0;
91 }

由于本人水平有限,文中不当和错误之处难以避免,欢迎大家批评指正,愿共同进步!!!

时间: 2024-10-29 02:46:43

二叉树题目总结(一)的相关文章

南阳 oj 重建二叉树 题目756

 #include <stdio.h> #include <malloc.h> #include <string.h> //二叉链表 typedef struct node{ char data;//节点数据元素 struct node *lchild;//指向左孩子 struct node *rchild;//指向右孩子 }BiNode,*BTree; //利用后序和中序建立二叉树 void GetPreOrder(char *last,char *mid,BTr

二叉树题目合集

104. Maximum Depth of Binary Tree 找到二叉树的最大深度. public class Solution { public int maxDepth(TreeNode root) { if (root == null) { return 0; } int l = maxDepth(root.left) + 1; int r = maxDepth(root.right) + 1; return l > r ? l : r; } } 111. Minimum Depth

一道哈夫曼二叉树题目--稍微容易一点

答案是A,C, 要先画哈夫曼树, 总结一下, 哈夫曼编码树, 和哈夫曼树还是有点区别. 哈夫曼树的左右节点大小好像没关系(视频里听了一句), 编码树都可以左节点要小值. 原文地址:https://www.cnblogs.com/tekikesyo/p/10792452.html

ACM题目————二叉树的遍历

一.二叉树的后序遍历: 题目描述 给定一颗二叉树,要求输出二叉树的深度以及后序遍历二叉树得到的序列.本题假设二叉树的结点数不超过1000 输入 输 入数据分为多组,第一行是测试数据的组数n,下面的n行分别代表一棵二叉树.每棵二叉树的结点均为正整数,数据为0代表当前结点为空,数据为-1代表二叉 树数据输入结束,-1不作处理.二叉树的构造按照层次顺序(即第1层1个整数,第2层2个,第3层4个,第4层有8个......,如果某个结点不存在以 0代替). 输出 输出每棵二叉树的深度以及后序遍历二叉树得到

题目六:重建二叉树

/////////////////////////////////////////////////////////////////////////////////////// // // 9.题目六:重建二叉树 // 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出改二叉树 struct BinaryTreeNode { int m_iValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; BinaryTreeNode(int i

LeetCode 数组转二叉树 C#

把LeetCode二叉树题目的测试数组,转换成二叉树 class TreeNode { public int val; public TreeNode left; public TreeNode right; public TreeNode(int x) { val = x; } } class Tree { public static TreeNode CreateNode(int? val) { if (val == null) return null; return new TreeNod

剑指offer 重建二叉树

重建二叉树 题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回 思路:首先找到root,然后递归的重建root -> left,root -> right. /** * Definition for binary tree * struct TreeNode { * int val; * TreeNod

Luogu P1305 新二叉树

P1305 新二叉树 题目描述 输入一串二叉树,用遍历前序打出. 输入输出格式 输入格式: 第一行为二叉树的节点数n. 后面n行,每一个字母为节点,后两个字母分别为其左右儿子. 空节点用*表示 输出格式: 前序排列的二叉树 输入输出样例 输入样例#1: 6 abc bdi cj* d** i** j** 输出样例#1: abdicj 这道题其实很简单,在这里写下就是要让大家看一个简单的方法.(感谢javalyc童鞋) 1 #include <cstdio> 2 3 char a[100][3]

《剑指offer》— JavaScript(4)重建二叉树

重建二叉树 题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 实现代码 function reConstructBinaryTree(pre, vin) { if(!pre || pre.length===0){ return; } var root={ val:pre[0] }; for(var i