文章目录
红黑树的性质
- 每个节点要么是红的,要么是黑的
- 根节点是黑的
- 每个叶节点(即树尾端NIL指针或NULL节点)是黑的
- 若一个节点是红的,那么它的两个儿子都是黑的
- 对于任意节点而言,其到叶节点树尾端NIL指针的每条路径都包含相同数目的黑节点
有关树的算法实现代码(C++)
1、判断是否是树的子结构
核心:递归实现
//子结构pRoot2
//ps:约定空树不是任意一个树的子结构
class solution{
public:
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2){
if(pRoot1 == NULL || pRoot2 == NULL)
return fasle;
return IsSubtree(pRoot1,pRoot2) || HasSubtree(pRoot1 -> left, pRoot2) || HasSubtree(pRoot2 -> right, pRoot2)
}
bool IsSubtree(TreeNode* pRoot1,TreeNode* pRoot2){
if(pRoot1 == nullptr && pRoot2 == nullptr)
return true;
if(pRoot1 == nullptr || pRoot2 == nullptr)
return false;
if(pRoot1 -> val == pRoot2 -> val){
return IsSubtree(pRoot1 -> left, pRoot2 -> left) && IsSubtree(pRoot1 -> right,pRoot2 -> right);
}
else
return false;
}
}
2、生成二叉树的镜像
问题:将二叉树调整成其对应的二叉树镜像
class solution{
public:
void Mirror(TreeNode *pRoot){
//递归实现
if(pRoot==null)
return ;
TreeNode *pRight=pRoot->right;
pRoot->right=pRoot->left;
pRoot->left=pRight;
Mirror(pRoot->left);
Mirror(pRoot->right);
}
}
3、判断树是否的对称二叉树
问题:实现判断一棵树是否是对称的二叉树
class Solution{
public:
bool isSymmetrical(TreeNode* pRoot){
return isSymmetrical(pRoot,pRoot);
}
bool isSymmetrical(TreeNode* pRoot1,TreeNode* pRoot2){
if(pRoot1==NULL && pRoot2==NULL)
return true;
if(pRoot1==NULL || pRoot2==NULL)
return false;
if(pRoot1->val!=pRoot2->val)
return false;
return isSymmetrical(pRoot1->left, pRoot2->right) && isSymmetrical(pRoo1->right,pRoot2->left);
}
};
4.1、二叉树打印(顺序打印成单行)
问题描述,从上到下,从左到右打印二叉树
核心:构建一个Queue用于存在根节点,构建一个vector用于存放值
class Solution{
vector<int> PrintFromToptoBottom(TreeNode* root){
Queue<TreeNode*> Q;
vector<int> res;
Q.push(root)
while(!Q.empty()){
root=Q.front();
Q.pop();
if(!root){
continue;
}
vec.push_back(root->val);
Q.push(root->left);
Q.push(root->right);
}
return vec;
}
};
4.2、二叉树打印(之字形打印成多行)
问题:按之字形打印,第一行从左到右打印,第二行从右到左打印…
class Solution{
public:
vector<vector<int>> Print(TreeNode* pRoot){
vector<<vector>> res;
queue<TreeNdoe*> que;
que.push(pRoot);
if(pRoot==NULL)
return res;
bool even=false;
while(!que.empty()){
vector<int> vec;
int size=que.size();
for(int i=0;i<size;i++){
TreeNode* tmp=que.front();
que.pop();
vec.push_back(tmp->val);
if(tmp->left!=NULL)
que.push_back(tmp->left);
if(tmp->right!=NULL)
que.push_back(tmp->right);
}
if(even)
reverse(vec.begin(),vec.end());
res.push_back(vec);
even=!even;
}
return res;
}
};
5、二叉树的深度
class Solution{
public:
int TreeDepth(TreeNode* pRoot){
if(!pRoot)
return 0;
int left=TreeDepth(pRoot->left);
int right=TreeDepth(pRoot->right);
return max(left+1,right+1);
}
};
5、判断是否是平衡二叉树
问题:判断一棵树是否是平衡二叉树
核心:
- 空树是平衡二叉树
- 左右树高相差不能超过1
- 其子树也要是平衡二叉树
class Solution{
public:
bool IsBalanced_Solution(TreeNode* pRoot){
if(!pRoot)
return true;
int left=getDepth(pRoot->left);
int right=getDepth(pRoot->right);
if(abs(left-right)>1)
return false;
return IsBalanced_Solution(pRoot->left) && IsBalanced_Solution(pRoot->right);
}
int getDepth(TreeNode* pRoot){
if(!pRoot)
return 0;
int left=getDepth(pRoot->left);
int right=getDepth(pRoot->right);
return max(left+1,right+1);
}
};
6、将二叉搜索树变平衡
给你一棵二叉搜索树,请你返回一棵 平衡后 的二叉搜索树,新生成的树应该与原来的树有着相同的节点值。
如果一棵二叉搜索树中,每个节点的两棵子树高度差不超过 1 ,我们就称这棵二叉搜索树是 平衡的 。
如果有多种构造方法,请你返回任意一种。
输入:root = [1,null,2,null,3,null,4,null,null]
输出:[2,1,3,null,null,null,4]
解释:这不是唯一的正确答案,[3,1,4,null,2,null,null] 也是一个可行的构造方案。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> arr;
void build_array(TreeNode* root) {
if (root == nullptr) return ;
build_array(root -> left);
arr.push_back(root -> val);
build_array(root -> right);
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
int length = nums.size();
if (length == 0) return nullptr;
TreeNode* p_head = nullptr;
p_head = buildTree(nums, 0, length - 1);
return p_head;
}
TreeNode* buildTree(vector<int> & nums, int left, int right) {
if(left > right) return nullptr;
int mid = (left+ right) >> 1;
TreeNode* pNode = new TreeNode(nums[mid]);
if(left == right) return pNode;
pNode -> left = buildTree(nums, left, mid - 1);
pNode -> right = buildTree(nums, mid + 1, right);
return pNode;
}
TreeNode* balanceBST(TreeNode* root) {
build_array(root);
return sortedArrayToBST(arr);
}
};
7、二叉树的下一个节点
问题:对于中序遍历的二叉树,查找某个节点的下一个节点
核心:
- 当前节点存在右子树
- 当前节点不存在右子树
class Solution{
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode){
if(pNode==NULL)
return NULL;
if(pNode->right!=NULL){
pNode=pNode->right;
while(pNode->left!=NULL){
pNode=pNode->left;
}
return pNode;
}
while(pNode->next!=NULL){
if(pNode->next->left==pNode)
return pNode->next;
else
pNode=pNode->next;
}
return NULL;
}
};
8、二叉树的所有路径
输入:
1
/ \
2 3
\
5
输出: ["1->2->5", "1->3"]
解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> res;
if (root == nullptr) return res;
stack<pair<TreeNode*, string>> st; // 存储当前节点,与到当前节点的前面的字符串
pair<TreeNode*, string> temp = pair<TreeNode*, string>(root, to_string(root -> val));
st.push(temp);
while (!st.empty()) {
temp = st.top();
st.pop();
if (temp.first -> right != nullptr) {
st.push(pair<TreeNode*, string>(temp.first -> right, temp.second + "->" + to_string(temp.first -> right -> val)));
}
if (temp.first -> left != nullptr) {
st.push(pair<TreeNode*, string>(temp.first->left, temp.second + "->" + to_string(temp.first -> left ->val)));
}
if (temp.first -> left == nullptr && temp.first -> right == nullptr) {
res.push_back(temp.second);
}
}
return res;
}
};