目录
1. 之字形打印二叉树:
#include <bits/stdc++.h>
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x),left(nullptr),right(nullptr){}
};
std::vector<std::vector<int>> zigzagLevelOrder(TreeNode* root){
std::vector<std::vector<int> > result;
if(root == nullptr) return result;
std::queue<TreeNode*> q;
q.push(root);
bool leftToRight = true;
while(!q.empty())
{
int size = q.size();
std::vector<int> level;
for(int i = 0; i < size; i++)
{
TreeNode* temp = q.front();
q.pop();
if(temp->left) q.push(temp->left);
if(temp->right) q.push(temp->right);
if(leftToRight) level.push_back(temp->val);
else level.insert(level.begin(),temp->val);
}
leftToRight = ! leftToRight;
if(!level.empty()) result.push_back(level);
level.clear();
}
return result;
}
int main()
{
TreeNode* root = new TreeNode(3);
root->left = new TreeNode(9);
root->right = new TreeNode(20);
root->right->left = new TreeNode(15);
root->right->right = new TreeNode(7);
std::vector<std::vector<int>> result = zigzagLevelOrder(root);
// 输出结果
for (const auto& level : result) {
std::cout << "Level: ";
for (const auto& val : level) {
std::cout << val << " ";
}
std::cout << std::endl;
}
return 0;
}
时间复杂度On,空间复杂读On。
2.二叉树根节点到叶子节点和为指定值的路径-打印路径
//https://www.nowcoder.com/practice/840dd2dc4fbd4b2199cd48f2dadf930a?tpId=188&&tqId=36537&rp=1&ru=/activity/oj&qru=/ta/job-code-high-week/question-ranking
#include <iostream>
#include <vector>
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
void findPath(TreeNode* root, int sum, std::vector<int>& path, std::vector<std::vector<int>>& result) {
if (root == nullptr) {
return;
}
path.push_back(root->val); // 将当前节点的值加入路径中
if (root->left == nullptr && root->right == nullptr && root->val == sum) {
// 当前节点是叶子节点且节点值等于sum,将当前路径加入结果集
result.push_back(path);
}
findPath(root->left, sum - root->val, path, result); // 递归遍历左子树
findPath(root->right, sum - root->val, path, result); // 递归遍历右子树
path.pop_back(); // 回溯,将当前节点从路径中移除
}
std::vector<std::vector<int>> pathSum(TreeNode* root, int sum) {
std::vector<std::vector<int>> result;
std::vector<int> path;
findPath(root, sum, path, result);
return result;
}
int main() {
// 构建测试二叉树
TreeNode* root = new TreeNode(5);
root->left = new TreeNode(4);
root->right = new TreeNode(8);
root->left->left = new TreeNode(11);
root->left->left->left = new TreeNode(7);
root->left->left->right = new TreeNode(2);
root->right->left = new TreeNode(13);
root->right->right = new TreeNode(4);
root->right->right->left = new TreeNode(5);
root->right->right->right = new TreeNode(1);
int targetSum = 22;
std::vector<std::vector<int>> paths = pathSum(root, targetSum);
// 输出结果
for (const auto& path : paths) {
std::cout << "Path: ";
for (const auto& val : path) {
std::cout << val << " ";
}
std::cout << std::endl;
}
return 0;
}
时间复杂度On,空间复杂度On
3.是否有二叉树根节点到叶子节点和为指定值的路径-仅判断
#include <iostream>
#include <vector>
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
bool pathSum(TreeNode* root,int sum)
{
if(root == nullptr) return false;
if(root->left == nullptr && root->right == nullptr && sum - root->val ==0) return true;
return pathSum(root->left,sum-root->val) || pathSum(root->right,sum-root->val);
}
int main() {
// 构建测试二叉树
TreeNode* root = new TreeNode(5);
root->left = new TreeNode(4);
root->right = new TreeNode(8);
root->left->left = new TreeNode(11);
root->left->left->left = new TreeNode(7);
root->left->left->right = new TreeNode(2);
root->right->left = new TreeNode(13);
root->right->right = new TreeNode(4);
root->right->right->left = new TreeNode(5);
root->right->right->right = new TreeNode(1);
int targetSum = 22;
if(pathSum(root, targetSum)){
std::cout<<"true"<<std::endl;
}else{
std::cout<<"false"<<std::endl;
}
}
时间复杂度On,空间复杂度O1
4.由先序遍历二叉数转换成中序和后续遍历
中序遍历:
#include<bits/stdc++.h>
using namespace std;
string str;
int k = 0;
void dfs()
{
if(str[k]=='#')
{
k++;
return ;
}
char r = str[k++];
dfs(); //左子树
cout<<r<<' ';
dfs(); //右子树
}
int main()
{
cin>>str;
dfs();
return 0;
}
后续遍历:
#include<bits/stdc++.h>
using namespace std;
string str;
int k = 0;
void dfs()
{
if(str[k]=='#')
{
k++;
return ;
}
char r = str[k++];
dfs(); //左子树
dfs(); //右子树
cout<<r<<' ';
}
int main()
{
cin>>str;
dfs();
return 0;
}
5.给定这棵二叉树的前序遍历和中序遍历,求其后序遍历
不重建树:
#include <iostream>
using namespace std;
void postOrder(string pre, string in)
{
if (in.size())
{
char root = pre[0];
int k = in.find(root);
postOrder(pre.substr(1, k), in.substr(0, k));
postOrder(pre.substr(k + 1), in.substr(k + 1));
printf("%c", root);
}
}
int main()
{
string preOrder, inOrder;
while (cin >> preOrder >> inOrder)
postOrder(preOrder, inOrder), puts("");
return 0;
}
建树:
#include<iostream>
#include<string>
using namespace std;
string s1, s2;
typedef struct Node {
char data;
struct Node *lchild,*rchild;
}Node,*BTree;
BTree buildtreebyPI(int pl, int pr, int ml, int mr){
if(pl > pr) return NULL;
Node * root = new Node();
root->data = s1[pl];
int pos = s2.find(s1[pl]);
root->lchild = buildtreebyPI(pl+1, pl + pos - ml, ml, pos - 1); //划分左右子树
root->rchild = buildtreebyPI(pl + pos - ml + 1, pr, pos + 1, mr);
return root;
}
void Postmrder(BTree root) {
if(root == NULL) return;
Postmrder(root->lchild);
Postmrder(root->rchild);
cout<<root->data;
}
int main() {
while(cin>>s1>>s2) {
int n = s1.length();
Node* root = buildtreebyPI(0, n - 1, 0, n - 1);
Postmrder(root);
cout<<endl;
}
return 0;
}
6. 二叉树层序遍历
#include <bits/stdc++.h>
struct TreeNode
{
int val;
std::unique_ptr<TreeNode> left;
std::unique_ptr<TreeNode> right;
TreeNode(int x) : val(x),left(nullptr),right(nullptr){}
};
std::vector<std::vector<int>> levelorder(TreeNode* root)
{
std::vector<std::vector<int>> res;
if (root == nullptr)
return res;
std::queue<TreeNode*> q;
q.push(root);
while (!q.empty())
{
std::vector<int> level;
int size = q.size();
for (int i = 0; i < size; i++)
{
TreeNode* temp = q.front();
q.pop();
level.push_back(temp->val);
if (temp->left)
q.push(temp->left.get());
if (temp->right)
q.push(temp->right.get());
}
res.push_back(level);
level.clear();
}
return res;
}
int main()
{
std::unique_ptr<TreeNode> root= std::make_unique<TreeNode>(3);
root->left = std::make_unique<TreeNode>(9);
root->right = std::make_unique<TreeNode>(20);
root->right->left = std::make_unique<TreeNode>(15);
root->right->right = std::make_unique<TreeNode>(7);
std::vector<std::vector<int>> result = levelorder(root.get());
// 打印层序遍历结果
for (const auto& level : result)
{
for (const auto& value : level)
{
std::cout << value << " ";
}
std::cout << std::endl;
}
return 0;
}
7.判断二叉树是否对称
bool isCompare(TreeNode* root1,TreeNode* root2)
{
if(root1 == nullptr && root2 == nullptr) return true;
if(root1 == nullptr || root2 == nullptr || root1->val != root2->val)return false;
return isCompare(root1->left, root2->right) && isCompare(root1->right,root2->left);
}
#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x):val(x),left(nullptr),right(nullptr){}
};
TreeNode* buildTree(vector<int>& pre, vector<int>& vin)
{
int p = pre.size();
int v = vin.size();
if (p==0 ||v==0) return nullptr;
TreeNode* head = new TreeNode(pre[0]);
for(int i = 0; i < v; i++)
{
if(pre[0] == vin[i])
{
vector<int>leftpre(pre.begin()+1,pre.begin()+i+1);
vector<int>leftvin(vin.begin(),vin.begin()+i);
head->left=buildTree(leftpre, leftvin);
vector<int>rightpre(pre.begin()+i+1,pre.end());
vector<int>rightvin(vin.begin()+i+1,vin.end());
head->right=buildTree(rightpre, rightvin);
}
}
return head;
}
bool isCompare(TreeNode* root1,TreeNode* root2)
{
if(root1 == nullptr && root2 == nullptr) return true;
if(root1 == nullptr || root2 == nullptr || root1->val != root2->val)return false;
return isCompare(root1->left, root2->right) && isCompare(root1->right,root2->left);
}
int main()
{
vector<int> preorder = {1,2,4,7,3,5,6,8};
vector<int> inorder = {4,7,2,1,5,3,8,6};
TreeNode* root= buildTree(preorder,inorder);
bool result = isCompare(root,root);
cout<<(result ? "true":"false") <<endl;
return 0;
}
8.重建二叉树递归
给前序和中序遍历结果,重建出该二叉树并返回头节点。
#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x):val(x),left(nullptr),right(nullptr){}
};
TreeNode* buildTree(vector<int>& pre, vector<int>& vin)
{
int p = pre.size();
int v = vin.size();
if (p==0 ||v==0) return nullptr;
TreeNode* head = new TreeNode(pre[0]);
for(int i = 0; i < v; i++)
{
if(pre[0] == vin[i])
{
vector<int>leftpre(pre.begin()+1,pre.begin()+i+1);
vector<int>leftvin(vin.begin(),vin.begin()+i);
head->left=buildTree(leftpre, leftvin);
vector<int>rightpre(pre.begin()+i+1,pre.end());
vector<int>rightvin(vin.begin()+i+1,vin.end());
head->right=buildTree(rightpre, rightvin);
}
}
return head;
}
// 用于验证重建的二叉树是否正确 后序
void inorderTraversal(TreeNode* root) {
if (root == nullptr) {
return;
}
inorderTraversal(root->left);
inorderTraversal(root->right);
std::cout << root->val << " ";
}
int main()
{
vector<int> preorder = {1,2,4,7,3,5,6,8};
vector<int> inorder = {4,7,2,1,5,3,8,6};
TreeNode* root= buildTree(preorder,inorder);
std::cout << "Inorder Traversal: ";
inorderTraversal(root);
std::cout << std::endl;
return 0;
}
9. 二叉树深度
int maxDepth(TreeNode* root)
{
if(root == nullptr) return 0;
int lh = maxDepth(root->left);
int rh = maxDepth(root->right);
return 1 + max(lh,rh);
}
#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x):val(x),left(nullptr),right(nullptr){}
};
TreeNode* buildTree(vector<int>& pre, vector<int>& vin)
{
int p = pre.size();
int v = vin.size();
if (p==0 ||v==0) return nullptr;
TreeNode* head = new TreeNode(pre[0]);
for(int i = 0; i < v; i++)
{
if(pre[0] == vin[i])
{
vector<int>leftpre(pre.begin()+1,pre.begin()+i+1);
vector<int>leftvin(vin.begin(),vin.begin()+i);
head->left=buildTree(leftpre, leftvin);
vector<int>rightpre(pre.begin()+i+1,pre.end());
vector<int>rightvin(vin.begin()+i+1,vin.end());
head->right=buildTree(rightpre, rightvin);
}
}
return head;
}
int maxDepth(TreeNode* root)
{
if(root == nullptr) return 0;
int lh = maxDepth(root->left);
int rh = maxDepth(root->right);
return 1 + max(lh,rh);
}
int main()
{
vector<int> preorder = {1,2,4,7,3,5,6,8};
vector<int> inorder = {4,7,2,1,5,3,8,6};
TreeNode* root= buildTree(preorder,inorder);
int res = maxDepth(root);
cout << res <<endl;
return 0;
}
10.平衡二叉树
左右辆子树高度差的绝对值不超过1
#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x):val(x),left(nullptr),right(nullptr){}
};
TreeNode* buildTree(vector<int>& pre, vector<int>& vin)
{
int p = pre.size();
int v = vin.size();
if (p==0 ||v==0) return nullptr;
TreeNode* head = new TreeNode(pre[0]);
for(int i = 0; i < v; i++)
{
if(pre[0] == vin[i])
{
vector<int>leftpre(pre.begin()+1,pre.begin()+i+1);
vector<int>leftvin(vin.begin(),vin.begin()+i);
head->left=buildTree(leftpre, leftvin);
vector<int>rightpre(pre.begin()+i+1,pre.end());
vector<int>rightvin(vin.begin()+i+1,vin.end());
head->right=buildTree(rightpre, rightvin);
}
}
return head;
}
int getmaxDepth(TreeNode* root)
{
if(root == nullptr) return 0;
int lh = getmaxDepth(root->left);
int rh = getmaxDepth(root->right);
return 1 + max(lh,rh);
}
bool IsBalanced(TreeNode* root)
{
if(root == nullptr) return true;
if(!IsBalanced(root->left)) return false;
if(!IsBalanced(root->right)) return false;
int lh = getmaxDepth(root->left);
int rh = getmaxDepth(root->right);
if(abs(lh-rh)) return false;
return true;
}
int main()
{
vector<int> preorder = {1,2,4,7,3,5,6,8};
vector<int> inorder = {4,7,2,1,5,3,8,6};
TreeNode* root= buildTree(preorder,inorder);
cout<< (IsBalanced(root) ? "true" : "false") <<endl;
}
11 二叉树最近公共祖先
#include <bits/stdc++.h>
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x):val(x),left(nullptr),right(nullptr){}
};
TreeNode* buildtree(std::string & input)
{
if(input.empty() || input == "{}") return nullptr;
std::vector<std::string> nums;
std::stringstream ss(input.substr(1,input.length()-2));
std::string roots;
while(std::getline(ss,roots,','))
{
nums.push_back(roots);
}
TreeNode* root = new TreeNode(std::stoi(nums[0]));
std::queue<TreeNode*>q;
q.push(root);
int i = 1;
while(!q.empty() && i < nums.size())
{
TreeNode* temp = q.front();
q.pop();
if(nums[i] != "#"){
temp->left = new TreeNode(std::stoi(nums[i]));
q.push(temp->left);
}i++;
if(i < nums.size() && nums[i] != "#"){
temp->right = new TreeNode(std::stoi(nums[i]));
q.push(temp->right);
}i++;
}
return root;
}
TreeNode* LCA(TreeNode* root,int o1,int o2)
{
if(root ==nullptr || root->val == o1 || root->val ==o2)
return root;
TreeNode* left = LCA(root->left,o1,o2);
TreeNode* right = LCA(root->right,o1,o2);
if(left != nullptr && right != nullptr) return root;
else if(left != nullptr) return left;
else
return right;
return nullptr;
}
int lowerComm(TreeNode* root,int o1,int o2)
{
TreeNode* temp = LCA(root,o1,o2);
return temp->val;
}
int main()
{
std::string input = "{3,5,1,6,2,0,8,#,#,7,4}";
int o1 = 5,o2 = 1;
TreeNode* root = buildtree(input);
int a = lowerComm(root,o1,o2);
std::cout<<a<<std::endl;
return 0;
}
时间复杂度On,空间复杂度Ologn最坏On,二叉树退化成链表
12 由层序遍历二叉树数组重建二叉树
{3,5,1,6,2,0,8,#,#,7,4}
#include <bits/stdc++.h>
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x):val(x),left(nullptr),right(nullptr){}
};
TreeNode* buildtree(std::string & input)
{
if(input.empty() || input == "{}") return nullptr;
std::vector<std::string> nums;
std::stringstream ss(input.substr(1,input.length()-2));
std::string roots;
while(std::getline(ss,roots,','))
{
nums.push_back(roots);
}
TreeNode* root = new TreeNode(std::stoi(nums[0]));
std::queue<TreeNode*>q;
q.push(root);
int i = 1;
while(!q.empty() && i < nums.size())
{
TreeNode* temp = q.front();
q.pop();
if(nums[i] != "#"){
temp->left = new TreeNode(std::stoi(nums[i]));
q.push(temp->left);
}i++;
if(i < nums.size() && nums[i] != "#"){
temp->right = new TreeNode(std::stoi(nums[i]));
q.push(temp->right);
}i++;
}
return root;
}
void printTree(TreeNode* root)
{
if(root == nullptr) return ;
printTree(root->left);
std::cout<<root->val<<" ";
printTree(root->right);
}
int main()
{
std::string input = "{3,5,1,6,2,0,8,#,#,7,4}";
TreeNode* root = buildtree(input);
printTree(root);
return 0;
}