1.二叉树创建
class Solution
{
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin)
{
if(pre.size()<=0||vin.size()<=0)
return NULL;
TreeNode *root=new TreeNode(pre[0]);
//前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
for(int i=0;i<vin.size();i++)
{
if(pre[0]==vin[i])
{
root->left=reConstructBinaryTree(copy(pre,1,i),copy(vin,0,i-1));
root->right=reConstructBinaryTree(copy(pre,i+1,pre.size()-1),copy(vin,i+1,vin.size()-1));
break;
}
}
return root;
}
vector<int> copy(vector<int> array,int begin,int end)
{
vector<int> temp;
while(begin<=end)
{
temp.push_back(array[begin++]);
}
return temp;
}
};
int input;
scanf("%d",&input); //按先序建立二叉树
if(input == 0)
{
root = NULL; //置为NULL后结束
return root;
}
root = (TreeNode *)malloc(sizeof(TreeNode));
root ->val = input;
root->left = CreateTree(root->left);
root->right = CreateTree(root->right);
return root;
}
2.二叉树递归遍历
void preorder(Node* root)//先序遍历打印树的各个节点
{
if (root)
{
cout<<root->val<<" "; //访问当前节点的值
preorder(root->left); //递归遍历左子树
preorder(root->right); //递归遍历右子树
}
}
void inorder(Node* root)//中序遍历打印树的各个节点
{
if (root)
{
preorder(root->left); //递归遍历左子树
cout<<root->val<<" "; //访问当前节点的值
preorder(root->child); //递归遍历右子树
}
}
void postorder(Node* root)//后序遍历打印树的各个节点
{
if (root)
{
preorder(root->left); //递归遍历左子树
preorder(root->right); //递归遍历右子树
cout<<root->val<<" "; //访问当前节点的值
}
}
3.二叉树非递归遍历
//中序遍历
void InOrderWithoutRecursion1(TreeNode* root)
{
//空树
if (root == NULL)
return;
//树非空
TreeNode* p = root;
stack<TreeNode*> s;
while (!s.empty() || p)
{
//一直遍历到左子树最下边,边遍历边保存根节点到栈中
while (p)
{
s.push(p);
p = p->left;
}
//当p为空时,说明已经到达左子树最下边,这时需要出栈了
if (!s.empty())
{
p = s.top();
s.pop();
cout << setw(4) << p->val;
//进入右子树,开始新的一轮左子树遍历(这是递归的自我实现)
p = p->right;
}
}
}
三、
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<vector<int> > res;
vector<vector<int> > Print(TreeNode* pRoot)
{
if(!pRoot)
return res;
queue <TreeNode*> q;
q.push(pRoot);
vector<int> temp;
while (!q.empty())
{
int size=q.size();
for (int i=0;i<size;i++) { //一次处理一层的数据
TreeNode *node=q.front();
temp.push_back(node->val);
q.pop();
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
res.push_back(temp);
temp.clear();
}
return res;
}
};
之字形打印二叉树
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<vector<int> > res;
vector<vector<int> > Print(TreeNode* pRoot)
{
if(!pRoot)
return res;
queue <TreeNode*> q;
q.push(pRoot);
bool flag = 1;
vector<int> temp;
while (!q.empty())
{
int size=q.size();
for (int i=0;i<size;i++)
{ //一次处理一层的数据
TreeNode *node=q.front();
temp.push_back(node->val);
q.pop();
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
if(flag)
{
res.push_back(temp);
}
else
{
reverse(temp.begin(),temp.end());
res.push_back(temp);
}
flag =!flag;
temp.clear();
}
return res;
}
};
二叉树深度
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
int TreeDepth(TreeNode* pRoot)
{
if(pRoot == NULL)
return 0;
queue<TreeNode*> queTree;
queTree.push(pRoot);
int depth = 0;
while(!queTree.empty())
{
int size = queTree.size();
depth++;
while(size != 0)
{
TreeNode* temp = queTree.front();
queTree.pop();
if(temp->left)
queTree.push(temp->left);
if(temp->right)
queTree.push(temp->right);
size--;
}
}
return depth;
}
};
class Solution {
public:
int TreeDepth(TreeNode* pRoot){
if(!pRoot) return 0 ;
return max(1+TreeDepth(pRoot->left), 1+TreeDepth(pRoot->right));
}
};
否是平衡二叉树。
class Solution {
public:
int tree_deep(TreeNode* pRoot)
{
if(pRoot == NULL)
{
return 0;
}
int left = tree_deep(pRoot->left);
int right = tree_deep(pRoot->right);
return left > right?(left+1):(right+1);
}
bool IsBalanced_Solution(TreeNode* pRoot) {
if(pRoot == NULL)
{
return true;
}
int leftr = tree_deep(pRoot->left);
int rightr = tree_deep(pRoot->right);
int diff =abs(leftr - rightr);
if(diff > 1)
{
return false;
}
else
{
return true;
}
}
};
输入两棵二叉树A,B,判断B是不是A的子结构
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
{
if (!pRoot2) return false;
if (!pRoot1) return false;
return (check(pRoot1,pRoot2) || HasSubtree(pRoot1->left,pRoot2) || HasSubtree(pRoot1->right,pRoot2));
}
private:
bool check(TreeNode* pRoot1, TreeNode* pRoot2)
{
if (!pRoot2) return true;
if (!pRoot1) return false;
if (pRoot1->val == pRoot2->val) return (check(pRoot1->left,pRoot2->left)&&check(pRoot1->right,pRoot2->right));
return false;
}
};
变换为源二叉树的镜像。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
void Mirror(TreeNode *pRoot) {
if(pRoot == NULL)
{
return;
}
TreeNode *tem = NULL;
tem = pRoot->left;
pRoot->left = pRoot->right;
pRoot->right = tem;
Mirror(pRoot->left);
Mirror(pRoot->right);
}
};
二叉树中和为某一值的路径
class Solution {
private:
vector<vector<int> > result;
void findnode(TreeNode *root, const int expectNumber,int sum,vector<int> &path)
{
if (root == NULL)
{
return;
}
path.push_back(root->val);
sum += root->val;
if (!root->left && !root->right && sum == expectNumber)
{
result.push_back(path);
}
else {
findnode(root->left,expectNumber,sum,path);
findnode(root->right,expectNumber,sum,path);
}
path.pop_back();
sum -= root->val;
}
public:
vector<vector<int> > FindPath(TreeNode* root, int expectNumber)
{
vector<int> path;
findnode(root,expectNumber,0,path);
return result;
}
};
判断该数组是不是某二叉搜索树的后序遍历的结果
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
int sizeq = sequence.size();
if(sizeq == 0)
{
return false;
}
else if(sizeq == 1)
{
return true;
}
return search_seq(sequence,0,sizeq-1);
}
bool search_seq(vector<int> s,int start,int end)
{
if(start > end)
{
return true;
}
int i = start;
while(s[i] < s[end])
{
++i;
}
for(int j=i;j<end;j++)
{
if(s[j] < s[end])
{
return false;
}
}
return search_seq(s,0,i-1) && search_seq(s,i+1,end-1);
}
};
二叉搜索树转换成一个排序的双向链表
/*
非递归中序遍历,加个指针pre记录上一次出栈值
*/
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
TreeNode *head = NULL, *pre = NULL;//head 输出,pre记录上一次出栈值
stack<TreeNode*> s;
while (pRootOfTree || !s.empty())
{
while (pRootOfTree)
{
s.push(pRootOfTree);
pRootOfTree = pRootOfTree->left;
}
if (!s.empty())
{
pRootOfTree = s.top();
s.pop();
if (pre != NULL)
{
pre->right = pRootOfTree;
pRootOfTree->left = pre;
}
else//pre为空,表示s第一次出栈,第一次出栈值为最左值,即输出值
{
head = pRootOfTree;
}
pre = pRootOfTree;
pRootOfTree = pRootOfTree->right;
}
}
return head;
}
};
中序遍历顺序的下一个结点并且返回
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if(pNode==nullptr) return nullptr; //情况1.空树,返回空
if(pNode->right!=nullptr) //情况2.有右子树,则本节点的下一个节点即是其右子树的最左的子节点
{
TreeLinkNode*p=pNode->right;
while(p->left!=nullptr) {p=p->left;}
return p;
}
while(pNode->next!=nullptr) //情况3.1没有右子树,则本节点的下一个节点即是 满足:本节点的父节点(1)是他父节点(2)的左子节点 这一条件时,返回(2)
{
if(pNode->next->left==pNode) return pNode->next;
pNode=pNode->next;
}
return nullptr; //情况3.2 已经找到根节点了,结束上面的循环,那么本节点的下一个节点就指向nullptr
}
};
给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
int count = 0;
TreeNode *res = NULL;
void inOrder(TreeNode * root,int k)
{
if (root == NULL)
{
return;
}
inOrder(root->left,k);
count++;
if(count == k)
{
res = root;
}
inOrder(root->right,k);
}
TreeNode* KthNode(TreeNode* pRoot, int k)
{
if(!pRoot)
return pRoot;
inOrder(pRoot,k);
return res;
}
};
求二叉树中节点的个数
size_t size(Node* root)//求树中的节点个数
{
size_t count = 0;
if (NULL == root)
{
count = 0;
}
else
{
//当前节点 = 左子树节点 + 右子树节点 + 1
count = size(root->left) + size(root->right)+ 1;
}
return count;
}
求二叉树中叶子节点的个数
size_t getleafsize(Node* root)//求叶节点的个数
{
if (NULL == root)//空树
{
return 0;
}
if (NULL == root->left && NULL == root->right)//左叶节点右节点均为空,即
{
return 1;
}
else//左子树的叶节点+右子树的叶节点
{
return getleafsize(root->left)+getleafsize(root->right);
}
}
求二叉树第K层的节点个数(假设根节点为第1层)
size_t getklevelsize(Node* root,size_t k)//树中第k层的节点个数
{
assert(k>0);
size_t count = 0;
if (NULL == root)
{
return 0;
}
if (k == 1)
{
count++;
}
else
{
count = getklevelsize(root->left,k-1)
+ getklevelsize(root->right,k-1);
}
return count;
}
判断一个节点是否在二叉树中
bool _Find(Node* root,const T& data) //查找指定数据的节点
{
if (NULL == root)
{
return false;
}
else if (root->val== data)
{
return true;
}
else
{
bool isIn = false;
if (root->left && !isIn)
isIn = _Find(root->left,data);
if (root->right && !isIn)
isIn = _Find(root->right,data);
return isIn;
}
}
求二叉树中最远的两个节点的距离
int _RemoteDistance1(Node* root,int& distance)
{
if (NULL == root)
{
return 0;
}
int tmp = _Depth(root->_left)+_Depth(root->_right);//递归去求每棵子树的最远距离
if (distance < tmp)//用全局变量保存每棵子树的最远距离,并不断更新
{
distance = tmp;
}
return distance;
}
求二叉查找树的公共祖先
/*1 如果两个节点都比当前节点小, 那公共祖先必然是当前节点的左子树上, 所以递归左子树;
2 如果两个节点都比当前节点大, 那么同上, 递归右子树;
3 如果两个节点有一个为当前节点, 则当前节点为公共节点; 如果两个节点分别比当前节点小和大, 那么当前节点必为公共节点.*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL || p == NULL || q == NULL)
return root;
if(p->val > root->val && q->val > root->val)
return lowestCommonAncestor(root->right, p, q);
else if(p->val < root->val && q->val < root->val)
return lowestCommonAncestor(root->left, p, q);
else
return root;
}
};
求二叉树的公共祖先
/*直到递归到某节点满足一定的条件, 返回该节点; 否则继续递归, 若到叶子节点, 返回空. 那么最终返回的必然为两个被求节点的公共祖先.
具体思路:
1 如果当前节点为空, 返回空;
2 如果当前节点为两个节点中的一个, 或者当前节点恰好是两个节点的父亲节点, 那么返回该节点;
3 递归遍历当前节点左子树;
4 递归遍历当前节点右子树;
5 如果3 和 4 返回的都不是空, 那么当前节点必为公共祖先, 返回当前节点;
6 如果5不满足, 但3返回的不为空, 则返回3返回的节点指针;
7 如果5不满足, 但4返回的不为空, 则返回4返回的节点指针*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL)
return NULL;
if(root == p || root == q || (root->left == p && root->right == q) || (root->left == q && root->right == p))
return root;
TreeNode* leftReturn = lowestCommonAncestor(root->left, p, q);
TreeNode* rightReturn = lowestCommonAncestor(root->right, p, q);
if(leftReturn != NULL && rightReturn != NULL)
return root;
if(leftReturn != NULL)
return leftReturn;
if(rightReturn != NULL)
return rightReturn;
}
};