二叉树
二叉树性质
- 在第n层,最多有 2 n − 1 2^{n-1} 2n−1个节点
- 深度为n层的二叉树,最多有 2 n − 1 2^{n}-1 2n−1个节点
- 任何一个二叉树,叶节点有 n 0 n_{0} n0个,度为2的非叶节点有 n 2 n_{2} n2个,那么 n 0 = n 2 + 1 n_{0}=n_{2}+1 n0=n2+1
- 具有n个节点的完全二叉树,的高度为 ⌊ l o g 2 n ⌋ + 1 \lfloor log_{2}n \rfloor +1 ⌊log2n⌋+1, ⌊ ⌋ \lfloor\rfloor ⌊⌋表示向下取整
二叉树遍历
- 前序遍历:中左右
- 中序遍历:左中右
- 后序遍历:左右中
递归方式
如果用递归方式,那么遍历顺序是固定的,打印节点的时间决定了是那种遍历。拿上图来说,对于F左侧,顺序是FCA(A左子树为空)A(A右子树为空)ACDB(B左子树为空)D…
- 前序遍历:在第一次进入打印节点
- 中序遍历:第二次打印节点
- 后序遍历:第三次打印节点
代码
#include <iostream>
#include <stdlib.h>
//节点
struct Node {
int value;
Node* left;
Node* right;
Node(int v = 0): value(v), left(nullptr), right(nullptr) {}
};
//向二叉树插入元素
void insert_tree(Node* &root, int value) {
if (nullptr == root) {
root = new Node(value);
return;
}
if (value < root->value) {
insert_tree(root->left, value);
} else if (value > root->value) {
insert_tree(root->right, value);
}
}
//生成二叉树
void create_tree(Node* root, int root_value, int size) {
root->value = root_value++;
for (int i = 0; i <= size; ++i) {
insert_tree(root, i);
}
}
//销毁二叉树
void destroy_tree(Node* root) {
if (root == nullptr) {
return;
}
destroy_tree(root->left);
destroy_tree(root->right);
delete root;
}
//前序遍历
void pre_order_recur(Node* head) {
if (head == nullptr) {
return;
}
std::cout << head->value << " ";
pre_order_recur(head->left);
pre_order_recur(head->right);
}
//中序遍历
void in_order_recur(Node* head) {
if (head == nullptr) {
return;
}
in_order_recur(head->left);
std::cout << head->value << " ";
in_order_recur(head->right);
}
//后序遍历
void post_order_recur(Node* head) {
if (head == nullptr) {
return;
}
post_order_recur(head->left);
post_order_recur(head->right);
std::cout << head->value << " ";
}
int main(void)
{
Node* root = new Node();
create_tree(root, 5, 9);
pre_order_recur(root);
std::cout << std::endl;
in_order_recur(root);
std::cout << std::endl;
post_order_recur(root);
std::cout << std::endl;
destroy_tree(root);
return 0;
}
非递归方式
非递归遍历需要一个栈辅助,把节点按照顺序压入栈中。前序遍历和后序遍历在循环开始前都需要头结点先入队。
- 前序遍历:弹出就打印,有右就压右,有左就压左
- 中序遍历:根不为空左递归(压栈),根若为空右递归,右递归时再打印
- 后序遍历:需要两个栈;弹出压入s2,有左就压左(s1),有右就压右(s1),最后才打印
- 层序遍历:层序遍历,使用队列
1.头结点入队
2.头结点弹出打印
3.左右子节点先后入队列
4.按顺序弹出打印,并将子节点先后入队
代码
#include <iostream>
#include <stack>
//节点
struct Node {
int value;
Node* left;
Node* right;
Node(int v = 0): value(v), left(nullptr), right(nullptr) {}
};
//向二叉树插入元素
void insert_tree(Node* &root, int value) {
if (nullptr == root) {
root = new Node(value);
return;
}
if (value < root->value) {
insert_tree(root->left, value);
} else if (value > root->value) {
insert_tree(root->right, value);
}
}
//生成二叉树
void create_tree(Node* root, int root_value, int size) {
root->value = root_value++;
for (int i = 0; i <= size; ++i) {
insert_tree(root, i);
}
}
//销毁二叉树
void destroy_tree(Node* root) {
if (root == nullptr) {
return;
}
destroy_tree(root->left);
destroy_tree(root->right);
delete root;
}
//前序遍历
void pre_order(Node* head) {
if (head != nullptr) {
std::stack<Node*> s;
s.push(head);
while (!s.empty()) {
head = s.top();
s.pop();
std::cout << head->value << " ";
if (head->right != nullptr) {
s.push(head->right);
}
if (head->left != nullptr) {
s.push(head->left);
}
}
}
}
//中序遍历
void in_order(Node* head) {
if (head != nullptr) {
std::stack<Node*> s;
while (!s.empty() || head != nullptr) {
if (head != nullptr) {
s.push(head);
head = head->left;
} else {
head = s.top();
s.pop();
std::cout << head->value << " ";
head = head->right;
}
}
}
}
//后序遍历
void post_order(Node* head) {
if (head != nullptr) {
std::stack<Node*> s1;
std::stack<Node*> s2;
s1.push(head);
while (!s1.empty()) {
head = s1.top();
s1.pop();
s2.push(head);
if (head->left != nullptr) {
s1.push(head->left);
}
if (head->right != nullptr) {
s1.push(head->right);
}
}
while (!s2.empty()) {
head = s2.top();
std::cout << head->value << " ";
s2.pop();
}
}
}
//层序遍历,使用队列
//1.头结点入队
//2.头结点弹出打印
//3.左右子节点先后入队列
//4.按顺序弹出打印,并将子节点先后入队
void level_order(Node* head) {
std::queue<Node*> q;
q.push(head);
Node *node;
while (!q.empty()) {
node = q.front();
std::cout << node->value << std::endl;
q.pop();
if (node->left != nullptr) {
q.push(node->left);
}
if (node->right != nullptr) {
q.push(node->right);
}
}
}
int main(void)
{
Node* root = new Node();
create_tree(root, 5, 9);
pre_order(root);
std::cout << std::endl;
in_order(root);
std::cout << std::endl;
post_order(root);
std::cout << std::endl;
destroy_tree(root);
return 0;
}