前段时间总结了一下关于树的算法,上传到博客,以后方便查看。
目录
二叉树的下一个节点
/*
二叉树的下一个节点
给定一颗二叉树和其中一个节点,找到中序遍历的下一个节点,树中有指向左、右两个子树的指针,还有
指向父节点的指针
*/
Struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode* parent;
TreeNode(int x) : val(x), left(NULL), rihgt(NULL), parent(NULL){}
};
class Solution{
public:
TreeNode* getNext(TreeNode* node){
if(node == NULL){
return NULL;
}
if(node->right != NULL){ //判断节点的右子树是否为空
TreeNode* next = node->right;
while(next->left != NULL){
next = next->left;
}
return next;
}
while(node->parent != NULL){ //判断父节点是否为空
TreeNode* next = node->parent;
if(next->left == node){
return next;
}
node = next;
}
return NULL;
}
}
二叉树的镜像
/*
二叉树的镜像
操作给定的二叉树,将其变换为源二叉树的镜像。
*/
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution
{
public:
Solution();
~Solution();
// 递归版本
void MirrorRecur(TreeNode* node){
if(node == NULL){
return;
}
TreeNode* tmp = node->left;
node->left = node->right;
node->right = tmp;
MirrorRecur(node->left);
MirrorRecur(node->right);
}
// 非递归版本
void MirrorNonrecur(TreeNode* node){
if(node == NULL){
return;
}
stack<TreeNode*> tmp;
tmp.push(node);
while(!tmp.empty()){
TreeNode* cur = tmp.top();
tmp.pop();
if(cur->left != NULL || cur->right != NULL){
TreeNode* tmp = cur->left;
cur->left = cur->right;
cur->right = tmp;
}
if(cur->right != NULL){
tmp.push(cur->right);
}
if(cur->left != NULL){
tmp.push(cur->left);
}
}
}
};
对称二叉树
/*
对称二叉树
实现一个函数,判断一颗二叉树是不是对称二叉树
*/
class Solution
{
public:
Solution();
~Solution();
// 递归版本
bool isSymRecur(TreeNode* node){
if(node == NULL){
return true;
}
return isSymCore(node->left, node->right);
}
bool isSymRecurCore(TreeNode* node1, TreeNode* node2){
if(node1 == NULL && node2 == NULL){
return true;
}
if(node1 == NULL || node2 == NULL || node1->val != node2->val){
return false;
}
return isSymCore(node1->left, node2->right) && isSymCore(node1->rihgt, node2->left);
}
// 非递归版本
bool isSymNonrecur(TreeNode* node){
if(node == NULL){
return true;
}
stack<TreeNode*> s1;
stack<TreeNode*> s2;
s1.push(node);
s2.push(node);
while(!s1.empty() && s2.empty()){
TreeNode* cur1 = s1.top();
s1.pop();
TreeNode* cur2 = s2.top();
s2.pop();
if(cur1 == NULL && cur2 == NULL){
continue;
}
if(cur1 == NUL || cur2 == NULL || cur1->val != cur2->val){
return false;
}
s1.push(cur1->rihgt);
s1.push(cur1->left);
s2.push(cur2->left);
s2.push(cur2->right);
}
if(s1.empty() && s2.empty()){
return true;
}
return false;
}
};
树的子结构
/*
树的子结构
输入两棵二叉树A、B,判断B是不是A的子结构(ps:我们约定空树不是任意一个树的子结构)
*/
class Solution
{
public:
Solution();
~Solution();
// 递归版本
bool hasSubtreeRecur(TreeNode* node1, TreeNode* node2){
if(node1 == NULL || node2 == NULL){
return false;
}
return isSubtreeRecur(node1, node2)
|| hasSubtreeRecur(node1->left, node2)
|| hasSubtreeRecur(node1->right, node2);
}
bool isSubtreeRecur(TreeNode* node1, TreeNode* node2){
if(node2 == NULL){
return true;
}
if(node1 == NULL){
return false;
}
if(node1->val == node2->val){
return isSubtreeRecur(node1->left, node2->left)
&& isSubtreeRecur(node1->right, node2->right);
}
return false;
}
// 非递归版本
bool hasSubtreeNonrecur(TreeNode* node1, TreeNode* node2){
if(node1 == NULL || node2 == NULL){
return false;
}
queue<TreeNode*> tmp;
tmp.push(node1);
while(!tmp.empty()){
TreeNode* cur = tmp.front();
tmp.pop();
bool target = false;
if(cur->val == node2->val){
target = isSubtree(cur, node2);
}
if(target){
return true;
}
if(cur->left){
tmp.push(cur->left);
}
if(cur->right){
tmp.push(cur->right);
}
}
return false;
}
bool isSubtreeNonrecur(TreeNode* node1, TreeNode* node2){
stack<TreeNode*> s1;
stack<TreeNode*> s2;
s1.push(node1);
s2.push(node2);
while(!s1.empty() && !s2.empty()){
TreeNode* cur1 = s1.top();
s1.pop();
TreeNode* cur2 = s2.top();
s2.pop();
if(cur2 == NULL){
continue;
}
if(cur1 == NULL || cur1->val != cur2->val){
return false;
}
s1.push(cur1->right);
s1.push(cur1->left);
s2.push(cur2->right);
s2.push(cur2->left);
}
if(s2.empty()){
return true;
}
return false;
}
};
二叉树的路径
/*
二叉树中的和为某一值的路径
输入一棵二叉树和一个整数,打印二叉树中节点值的和为输入整数的路径。从树根节点往下直到叶节点
形成一条路径。
*/
class Solution
{
public:
Solution();
~Solution();
vector<vector<int> > findPath(TreeNode* root, int num){
vector<vector<int> > all;
if(root == NULL){
return all;
}
vector<int> path;
findPathCore(root, all, path, num);
return all;
}
void findPathCore(TreeNode* root, vector<vector<int> >& all, vector<int>& path,
int num){
if(num < root->val){
return;
}
path.push_back(root->val);
if(num == root->val && root->left == NULL && root->right == NULL){
all.push_back(path);
path.pop_back();
return;
}
if(root->left){
findPathCore(root->left, all, path, num - root->val);
}
if(root->right){
findPathCore(root->right, all, path, num - root->val);
}
path.pop_back();
}
};
打印二叉树
/*
从上到下打印二叉树
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
*/
class Solution
{
public:
Solution();
~Solution();
vector<vector<int> > print(TreeNode* root){
vector<vector<int> > all;
if(root == NULL){
return all;
}
queue<TreeNode*> tmp;
tmp.push(root);
while(!tmp.empty()){
vector<int> path;
int size = tmp.size();
for(int i = 0; i < size; i++){
TreeNode* cur = tmp.front();
tmp.pop();
path.push_back(cur->val);
if(cur->left){
tmp.push(cur->left);
}
if(cur->right){
tmp.push(cur->right);
}
}
all.push_back(path);
}
return all;
}
};
重建二叉树
/*
重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
*/
class Solution
{
public:
Solution();
~Solution();
TreeNode* reBuildBinaryTree(vector<int> pre, vector<int> vin){
if(pre.size() == 0 || pre.size() != vin.size()){
return NULL;
}
vector<int> preL, preR, vinL, vinR;
int tar = 0;
while(pre[0] != vin[tar]){
tar++;
}
for(int i = 0; i < tar; i++){
preL.push_back(pre[i + 1]);
vinL.push_back(vin[i]);
}
for(int i = tar + 1; i < pre.size(); i++){
preR.push_back(pre[i]);
vinL.push_back(vin[i]);
}
TreeNode* cur = new TreeNode(pre[0]);
cur->left = reBuildBinaryTree(preL, vinL);
cur->right = reBuildBinaryTree(preR, vinR);
return cur;
}
};
二叉搜索树第K大的节点
/*
二叉搜索树的第K大的节点
给定一棵二叉搜索树,请找出其中的第k小的结点
*/
class Solution
{
public:
Solution();
~Solution();
TreeNode* kthNodeRecur(TreeNode* root, int k){
if(root == NULL || k <= 0){
return NULL;
}
return kthNodeRecurCore(root, k);
}
TreeNode* kthNodeRecurCore(TreeNode* root, int& k){
if(root == NULL || k <= 0){
return NULL;
}
TreeNode* target = NULL;
if(root->left){
target = kthNodeRecurCore(root->left, k);
}
if(target == NULL){
k--;
if(k == 0){
target = root;
}
}
if(target == NULL && root->right){
target = kthNodeRecurCore(root->right, k);
}
return target;
}
TreeNode* kthNodeNonrecur(TreeNode* root, int k){
if(root == NULL || k <= 0){
return NULL;
}
stack<TreeNode*> tmp;
TreeNode* cur = root;
while(cur != NULL || !tmp.empty()){
if(cur != NULL){
tmp.push(cur);
cur = cur->left;
}
else{
cur = tmp.top();
tmp.pop();
k--;
if(k == 0){
return cur;
}
cur = cur->right;
}
}
return NULL;
}
};
二叉搜索树变成双向链表
/*
二叉搜索树和双向链表
输入二叉搜索树,将二叉搜索树转换成一个排序的双向链表
*/
class Solution
{
public:
Solution();
~Solution();
TreeNode* convertRecur(TreeNode* root){
if(root == NULL){
return;
}
TreeNode* pre = NULL;
convertRecurCore(root, pre);
while(root->left != NULL){
root = root->left;
}
return root;
}
void convertRecurCore(TreeNode* root, TreeNode* &pre){
if(root == NULL){
return;
}
convertRecurCore(root->left, pre);
root->left = pre;
if(pre != NULL){
pre->right = root;
}
pre = root;
convertRecurCore(root->right, pre);
}
TreeNode* convertNonrecur(TreeNode* root){
if(root == NULL){
return NULL;
}
stack<TreeNode*> tmp;
TreeNode* cur = root;
TreeNode* pre = NULL;
while(cur != NULL || !tmp.empty()){
if(cur != NULL){
tmp.push(cur);
cur = cur->left;
}
else{
cur = tmp.top();
tmp.pop();
cur->left = pre;
if(pre != NULL){
pre->right = cur;
}
pre = cur;
cur = cur->right;
}
}
while(root->left != NULL){
root = root->left;
}
return root;
}
};
二叉搜索树的后序遍历
/*
二叉搜索树的后序遍历序列
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果
*/
class Solution
{
public:
Solution();
~Solution();
bool verifySquenceOfBST(vector<int> sequence){
if(sequence.size() == 0){
return false;
}
return verifySquenceOfBSTCore(sequence, 0, sequence.size() - 1);
}
bool verifySquenceOfBSTCore(vector<int> sequence, int start, int end){
if(start < 0 || end >= sequence.size() || start > end){
return false;
}
int i = start;
while(sequence[i] < sequence[end]){
i++;
}
for(int j = i; j < end; j++){
if(sequence[j] < sequence[size]){
return false;
}
}
return verifySquenceOfBSTCore(sequence, start, i - 1) &&
verifySquenceOfBSTCore(sequence, i, end - 1);
}
};
序列化二叉树
/*
序列化二叉树
实现两个函数,分别序列化和反序列化二叉树
*/
class Solution
{
public:
Solution();
~Solution();
char* serialize(TreeNode* root){
if(root == NULL){
return NULL;
}
string str;
serializeCore(root, str);
char* tmp = new char[str.size() + 1];
for(int i = 0; i < str.size(); i++){
tmp[i] = str[i];
}
tmp[str.size()] = '\0';
return tmp;
}
void serializeCore(TreeNode* root, string& str){
if(root == NULL){
str += '#';
return;
}
str += to_string(root->val);
str += ',';
serializeCore(root->left, str);
serializeCore(root->right, str);
}
TreeNode* deserialize(char* str){
if(str == NULL){
return NULL;
}
return deserializeCore(str);
}
TreeNode* deserializeCore(char* &str){
if(*str == '#'){
str++;
return NULL;
}
int num = 0;
while(*str != '/0' && *str != ','){
num = num * 10 + (*str - '0');
str++;
}
TreeNode* tmp = new TreeNode(num);
if(*str == '\0'){
return tmp;
}
else{
str++;
}
tmp->left = deserializeCore(str);
tmp->right = deserializeCore(str);
return tmp;
}
};
二叉树的深度
/*
二叉树的深度
输入一棵二叉树的根节点,求该树的深度
*/
class Solution
{
public:
Solution();
~Solution();
int getTreeDepthRecur(TreeNode* node){
if(node == NULL){
return 0;
}
int left = getTreeDepthRecur(node->left);
int right = getTreeDepthRecur(node->right);
return (left > right) ? (left + 1) : (right + 1);
}
int getTreeDepthNonrecur(TreeNode* node){
if(node == NULL){
return 0;
}
queue<TreeNode*> tmp;
tmp.push(node);
int depth;
while(!tmp.empty()){
depth++;
int size = tmp.size();
for(int i = 0; i < size; i++){
TreeNode* cur = tmp.front();
tmp.pop();
if(cur->left){
tmp.push(cur->left);
}
if(cur->right){
tmp.push(cur->right);
}
}
}
return depth;
}
};
平衡二叉树
/*
平衡二叉树
输入一颗二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树任意节点的左右子树深度相差
不超过1,那么它就是一颗平衡二叉树。
*/
class Solution
{
public:
Solution();
~Solution();
bool isBalanced(TreeNode* root){
if(root == NULL){
return false;
}
int depth = 0;
return isBalanced(root, depth);
}
bool isBalanced(TreeNode* root, int &depth){
if(root == NULL){
depth = 0;
return true;
}
int left = 0, right = 0;
if(isBalanced(root->left, left) && isBalanced(root->right, right)){
int diff = left - right;
if(abs(diff) <= 1){
depth = left > right ? (left + 1) : (right + 1);
return true;
}
}
return false;
}
};