二叉树
一、二叉树的构造
#include<cstdio>
using namespace std;
struct TreeNode{
int val;
TreeNode *left, *right; // 左右子树
TreeNode (int x) : val(x), left(NULL), right(NULL) {}
};
void preorder_print(TreeNode *node, int layer) { // 递归前序遍历
if(!node) return ;
for(int i = 0; i < layer; i++) printf("---");
printf("[%d]\n", node->val);
preorder_print(node->left, layer + 1);
preorder_print(node->right, layer + 1);
}
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;
preorder_print(&a, 0);
return 0;
}
二、二叉树的深度遍历
概览
同一种遍历模板,打印结果的位置不同
1. 前序遍历
先访问该节点,然后再遍历其子树
void preorder_print(TreeNode *node, int layer) { // 递归前序遍历
if(!node) return ;
for(int i = 0; i < layer; i++) printf("---");
printf("[%d]\n", node->val);
preorder_print(node->left, layer + 1);
preorder_print(node->right, layer + 1);
}
2. 中序遍历
先访问子树的左子树,然后再访问节点本身,再访问其右子树
void mid_print(TreeNode *node, int layer) {
if(!node) return ;
mid_print(node->left, layer + 1);
for(int i = 0; i < layer; i++) printf("---");
printf("[%d]\n", node->val);
mid_print(node->right, layer + 1);
}
3. 后序遍历
先访问其左右子树的全部节点再访问节点本身
void latter_print(TreeNode *node, int layer) {
if(!node) return ;
latter_print(node->left, layer + 1);
latter_print(node->right, layer + 1);
for(int i = 0; i < layer; i++) printf("---");
printf("[%d]\n", node->val);
}
三、二叉树转链表
#include<cstdio>
#include<vector>
using namespace std;
struct TN{
int val;
TN *left, *right;
TN(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution{
public:
void flatten(TN *root) {
TN *last = NULL;
preorder(root, last);
}
private:
void preorder(TN *node, TN *&last) {
if(!node) return ;
if(!node->left && !node->right) { // 如果是叶节点
last = node; // 则记为最后一个节点
return ;
}
TN *left = node->left; // 备份左右指针
TN *right = node->right;
TN *left_last = NULL; // 左右子树的最后一个节点
TN *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);
if(left_last) {
left_last->right = right; // 连接左右子树
}
right_last = last;
}
}
};
int main() {
TN 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);
TN *head = &a;
while(head) {
if(head->left) printf("ERROR\n");
printf("[%d]", head->val);
head = head->right;
}
return 0;
}