开宗明义:本系列基于小象学院林沐老师课程《面试算法 LeetCode 刷题班》,刷题小白,旨在理解和交流,重在记录,望各位大牛指点!
Leetcode学习之二叉树与图(2)
1、二叉树转链表 Leetcode 114.
题目来源:
L
e
e
t
c
o
d
e
114.
F
l
a
t
t
e
n
B
i
n
a
r
y
T
r
e
e
t
o
L
i
n
k
e
d
L
i
s
t
Leetcode \ 114. \ Flatten \ Binary \ Tree \ to \ Linked \ List
Leetcode 114. Flatten Binary Tree to Linked List
题目描述:给定一个二叉树,将该二叉树就地(in-place)转换为单链表。单链表中节点顺序为二叉树前序遍历顺序。
要求描述:
1.1 方法一
分析:
测试代码:
#include <stdio.h>
#include <vector>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) :val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
void flatten(TreeNode *root) {
vector<TreeNode*> node_vec;
preorder(root, node_vec);
for (int i = 1; i < node_vec.size(); i++) {
node_vec[i - 1]->left = NULL;
node_vec[i - 1]->right = node_vec[i];
}
}
private:
void preorder(TreeNode *node, vector<TreeNode *> &node_vec) {
if (!node) {
return;
}
node_vec.push_back(node);
preorder(node->left, node_vec);
preorder(node->right, node_vec);
}
};
int main() {
TreeNode a(1), b(2), c(5), d(3), e(4), f(6);
a.left = &b;
a.right = &c;
b.left = &d;
b.right = &e;
c.right = &f;
Solution solve;
solve.flatten(&a);
TreeNode *head = &a;
while (head)
{
if (head->left) {
printf("error!\n");
}
printf("[%d]", head->val);
head = head->right;
}
printf("\n");
system("pause");
return 0;
}
效果图:
1.2 方法二
分析:
测试代码:
#include <stdio.h>
#include <vector>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) :val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
void flatten(TreeNode *root) {
TreeNode *last = NULL;//末尾节点
preorder(root, last);
}
private:
void preorder(TreeNode *node, TreeNode *&last) {
if (!node) {//为空返回
return;
}
if (!node->left && !node->right) {//这个节点没有左右子树,为最终的叶节点
last = node;
return;
}
TreeNode *left = node->left;//备份左右指针
TreeNode *right = node->right;
TreeNode *left_last = NULL;//左右子树的最后一个节点
TreeNode *right_last = NULL;
if (left) {
preorder(left, left_last);//若有左子树,递归将左子树变成单链表
node->left = NULL;
node->right = left;
last = left_last;//将该节点的last保存为左子树的last
}
if (right) {//若有右子树,递归将右子树转化为单链表
preorder(right, right_last);//若node找到左子树的最后一个节点(有左子树)
if (left_last) {
left_last->right = right;
}
last = right_last;
}
}
};
int main() {
TreeNode a(1), b(2), c(5), d(3), e(4), f(6);
a.left = &b;
a.right = &c;
b.left = &d;
b.right = &e;
c.right = &f;
Solution solve;
solve.flatten(&a);
TreeNode *head = &a;
while (head)
{
if (head->left) {
printf("error!\n");
}
printf("[%d]", head->val);
head = head->right;
}
printf("\n");
system("pause");
return 0;
}
效果图:
2、二叉树层次遍历
描述:二叉树层次遍历,又称宽度优先搜索,按树的层次依次访问树的结点。层次遍历使用队列对遍历节点进行存储,先进入队列的结点,优先遍历拓展其左孩子与右孩子。
分析:
测试代码:
#include <stdio.h>
#include <vector>
#include <queue>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) :val(x), left(NULL), right(NULL) {}
};
void DFS_print(TreeNode* root) {//宽度优先搜索二叉树
queue<TreeNode *> Q;
Q.push(root);
while (!Q.empty())
{
TreeNode *node = Q.front();
Q.pop();
printf("[%d]\n", node->val);
if (node->left) {
Q.push(node->left);
}
if (node->right) {
Q.push(node->right);
}
}
}
int main() {
TreeNode a(1), b(2), c(5), d(3), e(4), f(6);
a.left = &b;
a.right = &c;
b.left = &d;
b.right = &e;
c.right = &f;
DFS_print(&a);
system("pause");
return 0;
}
效果图:
3、侧面观察二叉树(二叉树宽搜) Leetcode 199.
题目来源:
L
e
e
t
c
o
d
e
199.
B
i
n
a
r
y
T
r
e
e
R
i
g
h
t
S
i
d
e
V
i
e
w
Leetcode \ 199. \ Binary \ Tree \ Right \ Side \ View
Leetcode 199. Binary Tree Right Side View
题目描述:给定一个二叉树,假设从该二叉树的右侧观察它,将观察到的节点按照从上到下的顺序输出。
要求描述:
分析:
测试代码:
#include <stdio.h>
#include <vector>
#include <queue>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) :val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
vector<int> rightSideView(TreeNode *root) {
vector<int> view;//按层遍历的最后一个节点
queue<pair<TreeNode*, int>> Q;
//宽度优先搜索队列<节点,层数>
if (root) {//根节点非空时,将<root,0>push进入队列
Q.push(make_pair(root, 0));
}
while (!Q.empty())
{
TreeNode *node = Q.front().first;//搜索节点
int depth = Q.front().second;//待搜索节点的层数
Q.pop();
if (view.size() == depth) {
view.push_back(node->val);//第一个赋初值
}
else
{
view[depth] = node->val;//更新
}
if (node->left) {
Q.push(make_pair(node->left, depth + 1));
}
if (node->right) {
Q.push(make_pair(node->right, depth + 1));
}
}
return view;
}
};
int main() {
TreeNode a(1), b(2), c(5), d(3), e(4), f(6);
a.left = &b;
a.right = &c;
b.left = &d;
b.right = &e;
c.right = &f;
Solution solve;
vector<int> result = solve.rightSideView(&a);
for (int i = 0; i < result.size(); i++) {
printf("[%d]\n", result[i]);//结果vector
}
system("pause");
return 0;
}
效果图: