前言 二叉树遍历,一般分为广度优先遍历(BFS)和深度优先遍历(DFS),其中深度优先遍历---前中后序遍历,一条道走到黑,前中后序遍历大部分会用到递归的方式,当然也会用非递归的栈的方式来实现,只不过非递归的时间复杂度更高;广度优先遍历---层次遍历,依赖队列的方式来实现;
// 1
// / \
// 2 3
// / \ \
//4 5 6
// 前序遍历顺序:[1 2 4 5 3 6]
// 中序遍历顺序:[4 2 5 1 3 6]
// 后序遍历顺序:[4 5 2 6 3 1]
// 层次遍历顺序:[1 2 3 4 5 6]
1.层序遍历
解释:根据返回的结果,层序遍历输出各节点的值,首个值是所返回的根节点的值。
其中:null 表示是空节点
*/
#include <iostream>
#include <vector>
#include <algorithm>
#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<vector<int>> levelOrder(TreeNode* root) {
vector <vector <int>> ret;
if (!root) return ret;
queue <TreeNode*> q;
q.push(root);
while (!q.empty()) {
int currentLevelSize = q.size();
ret.push_back(vector <int> ());
for (int i = 1; i <= currentLevelSize; ++i) {
auto node = q.front(); // 队列的头
q.pop();
ret.back().push_back(node->val); //pop出队列的节点时,把队列中节点的值存于二维vector,back()函数表示得到数组的最后一个单元的引用
cout << node->val << endl;
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
}
return ret;
}
};
int main() {
vector<string> vec = {"3","9","20","null","null","15","7"}; // [[3],[9,20],[15,7]]
// 初始化一棵树
// 3
// / \
// 9 20
// / \
// 15 7
TreeNode* root = new TreeNode(3);
TreeNode* a1 = new TreeNode(9);
TreeNode* a2 = new TreeNode(20);
TreeNode* b1 = new TreeNode(15);
TreeNode* b2 = new TreeNode(7);
root->left = a1;
root->right = a2;
a2->left = b1;
a2->right = b2;
Solution solution;
vector<vector<int>> matrix = solution.levelOrder(root);
}
2.前中后前序遍历(递归方式)
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
/// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
/// Simulation
/// Time Complexity: O(n^2)
/// Space Complexity: O(n)
class Solution {
public:
TreeNode* insertIntoMaxTree(TreeNode* root, int val) {
vector<int> vec = {14,3,8,2,9};
dfs(root, vec);
vec.push_back(val);
return construct(vec, 0, vec.size() - 1);
}
TreeNode* construct(const vector<int>& A, int l, int r){
if(l > r) return NULL;
int best_val = A[l], best_index = l;
for(int i = l + 1; i <= r; i ++)
if(A[i] > best_val)
best_val = A[i], best_index = i;
TreeNode* retNode = new TreeNode(A[best_index]);
retNode->left = construct(A, l, best_index - 1);
retNode->right = construct(A, best_index + 1, r);
return retNode;
}
void dfs(TreeNode* root, vector<int>& A){
if(!root) return;
dfs(root->left, A);
A.push_back(root->val);
dfs(root->right, A);
}
// 前序遍历
void print1BST(TreeNode* root) {
if (!root) {
return;
}
cout << "print1BST: "<< root->val << endl;
if (root->left) {
print1BST(root->left);
}
if (root->right) {
print1BST(root->right);
}
}
// 中序遍历
void print2BST(TreeNode* root) {
if (!root) {
return;
}
if (root->left) {
print3BST(root->left);
}
cout << "print2BST: "<< root->val << endl;
if (root->left) {
print3BST(root->right);
}
}
// 后序遍历
void print3BST(TreeNode* root) {
if (!root) {
return;
}
if (root->left) {
print3BST(root->left);
}
if (root->left) {
print3BST(root->right);
}
cout << "print3BST: "<< root->val << endl;
}
// 层序遍历
// 1)首先利用队列先进先出的规则,把根节点放进队列,然后用一个vector来保存根节点的值,
// 2)然后取出根节点的左节点和右节点放进队列,当pop根节点后,此时轮到保存左节点和右节点的值,然后pop,直到队列为空,继续下一层遍历
void printLevel(TreeNode* root) {
vector<int> vec;
if(root == nullptr) {
return;
}
queue<TreeNode*> que;
que.push(root);
while(!que.empty()) {
TreeNode* cur = que.front();
que.pop();
vec.push_back(cur->val);
cout << "printLevel: " << cur->val << endl;
if (cur->left) {
que.push(cur->left);
}
if (cur->right) {
que.push(cur->right);
}
}
}
3. 非递归的前中后序遍历
// 非递归的前序遍历
// 1)利用栈Stack先进后出的规则,先把根节点入栈,然后取出值存于vector,然后再把右节点和右左节点入栈,依次pop,直到栈为空
// 2)后序遍历可以将前序遍历改成 root -> right -> left,然后反转一下,就成了后序遍历 left->right->root
void preOrder(TreeNode *root) {
stack<TreeNode*> stackPointer;
vector<int> vec;
if (root == nullptr){
return;
}
stackPointer.push(root);
while (!stackPointer.empty()) {
TreeNode *node = stackPointer.top();
if(node == nullptr) {
continue;
}
vec.push_back(node->val);
stackPointer.push(node->right); // 先右子树,后左子树入栈,保持前序遍历 root -> left -> right
stackPointer.push(node->left);
stackPointer.pop();
}
for (int i = 0; i > 0; ++i) {
cout << "preOrder: " << vec[i] << endl;
}
}
// 非递归的中序遍历 left->root->right 入栈时,先入root,然后把left赋给root,此时出栈的是left->root
void inOrder(TreeNode *root) {
stack<TreeNode*> stack;
if (root == nullptr) {
return;
}
TreeNode *cur = root;
while (!stack.empty()) { // 保持 入栈 root->left,出栈left->root->right
while (cur != nullptr) {
stack.push(cur);
cur = cur->left;
}
TreeNode *node = stack.top();
// vec.push_back(node->val);
cout << "inOrder: " << node->val << endl;
cur = node->right;
}
}
// 非递归的后序遍历 left->right->root
void postOrder(TreeNode *root) {
stack<TreeNode*> stackPointer;
vector<int> vec;
if (root == nullptr){
return;
}
stackPointer.push(root);
while (!stackPointer.empty()) {
TreeNode *node = stackPointer.top();
if(node == nullptr) {
continue;
}
vec.push_back(node->val);
stackPointer.push(node->left); // 先左子树,后右子树入栈,保持出栈前序遍历 root -> right -> left,反转一下
stackPointer.push(node->right);
stackPointer.pop();
}
for (int i = 0; i > 0; --i) {
cout << "postOrder: " << vec[i] << endl;
}
}
4.二叉树的插入操作
/// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
TreeNode* insertIntoMaxTree(TreeNode* root, int val) {
vector<int> vec = {14,3,8,2,9};
dfs(root, vec);
vec.push_back(val);
return construct(vec, 0, vec.size() - 1);
}
TreeNode* construct(const vector<int>& A, int l, int r){
if(l > r) return NULL;
int best_val = A[l], best_index = l;
for(int i = l + 1; i <= r; i ++)
if(A[i] > best_val)
best_val = A[i], best_index = i;
TreeNode* retNode = new TreeNode(A[best_index]);
retNode->left = construct(A, l, best_index - 1);
retNode->right = construct(A, best_index + 1, r);
return retNode;
}
void dfs(TreeNode* root, vector<int>& A){
if(!root) return;
dfs(root->left, A);
A.push_back(root->val);
dfs(root->right, A);
}