* 先根序遍历(非递归版)
1 void PreOrder(TreeNode* root)
2 {
3 stack<TreeNode*> s;
4 TreeNode *p=root,*last_visit=NULL;
5 while(p||s.size()>0)
6 {
7 if(p)//走到最左 边走边访问 并进栈
8 {
9 cout<<p->val<<endl;
10 s.push(p);
11 p=p->left;
12 }
13 else//左边没有节点了
14 {
15 p=s.top();//弹出上一个节点
16 s.pop();
17 p=p->right;//转向右子树
18 }
19 }
20 }
* 中根序遍历(非递归版)
void InOrder(TreeNode* root)
{
stack<TreeNode*> s;
TreeNode *p=root,*last_visit=NULL;
while(p||s.size()>0)
{
if(p)//走到最左
{
s.push(p);
p=p->left;
}
else//左边没有节点了
{
p=s.top();//弹出上一个节点
s.pop();
cout<<p->val<<endl;//访问栈中弹出的节点
p=p->right;//转向右子树
}
}
}
* 后根序遍历(非递归版)
1 void PostOrder(TreeNode* root)
2 {
3 stack<TreeNode*> s;
4 TreeNode *p=root,*last_visit=NULL;//last_visit指针记录上次访问过的值,因为后根序 根节点最后访问 所以未访问根节点时 根节点还未退栈 所以需要判别右子树是否访问过
5 while(p||s.size()>0)
6 {
7 if(p)//走到最左
8 {
9 s.push(p);
10 p=p->left;
11 }
12 else//左边没有节点了
13 {
14 p=s.top();//弹出上一个节点
15 if(p->right&&p->right!=last_visit)//若上一个节点存在右子树 且 未被访问过 则转向右子树
16 {
17 s.push(p->right);//右子树进栈
18 p=p->right->left;//再转向右子树的左子树
19 }
20 else//p的左右子树都不存在才进行访问
21 {
22 last_visit=s.top();//记录下来本节点已经访问过了
23 cout<<s.top()->val<<endl;
24 s.pop();//将访问过的节点退栈
25 p=NULL;//指针指向空 下次进来判断栈内下一个元素
26 }
27 }
28 }
29 }
* 二叉树的层次遍历(利用队列)
1 void LevelOrder(TreeNode * root)
2 {
3 queue<TreeNode*> que;//队列
4 TreeNode* p;
5 que.push(root);//先将根节点放入队列
6 while(!que.empty())//队列不空
7 {
8 p=que.front();//取出队头结点
9 cout<<p->val<<endl;//访问队头结点
10 que.pop();//将队头结点从队列中移除
11 if(p->left)//若p存在左子树
12 que.push(p->left);
13 if(p->right)//若p存在右子树
14 que.push(p->right);
15 }
16 }
应用:
1、利用层次遍历 获得二叉树的深度
1 int GetBiTDepth(TreeNode* root)
2 { if(!root) return 0;
3 queue<TreeNode*> que;
4 TreeNode* p=root,*last=root;//初始化第一层最后一个节点为root
5 que.push(p);
6 int count=0;//记录层数
7 while(!que.empty())//队列不空
8 {
9 p=que.front();//取出队头结点
10 que.pop();//将队头结点从队列中移除
11 if(p->left)//若p存在左子树
12 que.push(p->left);
13 if(p->right)//若p存在右子树
14 que.push(p->right);
15 if(p==last)
16 {
17 count++;//若遇到本层最后一个节点 层数+1
18 last=que.back();//下一层最后一个节点为队列的尾部
19 }
20 }
21 return count;
22 }
2、递归求树的深度
int GetBiTDepth(TreeNode* root)
{
if(root==NULL) return 0;
else
{
int leftDepth=GetBiTDepth(root->left);
int rightDepth=GetBiTDepth(root->right);
return leftDepth>rightDepth?leftDepth+1:rightDepth+1;//树的深度为子树的最大高度加根节点
}
}
3、leetcode 107题 给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
1 //法1 利用stl中的queue库
2 vector<vector<int>> levelOrderBottom(TreeNode* root) {
3 vector<vector<int>> result;
4 if(!root) return result;
5 queue<TreeNode*> que;
6 TreeNode* p=root,*last=root;//初始化第一层最后一个节点为root
7 que.push(p);
8 vector<int> level_result;
9 while(!que.empty())//队列不空
10 {
11 p=que.front();//取出队头结点
12 level_result.push_back(p->val);
13 que.pop();//将队头结点从队列中移除
14 if(p->left)//若p存在左子树
15 que.push(p->left);
16 if(p->right)//若p存在左子树
17 que.push(p->right);
18 if(p==last)
19 {
20 result.push_back(level_result);
21 level_result.clear();
22 last=que.back();//下一层最后一个节点为队列的尾部
23 }
24 }
25 reverse(result.begin(),result.end());
26 return result;
27 }
1 //法2 利用数组模拟queue
2 vector<vector<int>> levelOrderBottom(TreeNode* root) {
3 vector<vector<int>> result;
4 vector<int> level_result;
5 if(!root) return result;
6 TreeNode* queue[10000];
7 TreeNode *p;
8 int rear=-1,front=-1;
9 int last=0;//代表每一层的最后一个
10 queue[++rear]=root;
11 while(front<rear)//队列不空
12 {
13 p=queue[++front];//将队头结点从队列中移除
14 level_result.push_back(p->val);
15 if(p->left)//若p存在左子树
16 queue[++rear]=p->left;
17 if(p->right)//若p存在右子树
18 queue[++rear]=p->right;
19 if(front==last)//当前节点是本层最后一个
20 {
21 result.push_back(level_result);
22 level_result.clear();
23 last=rear;//下一层最后一个节点为队列的尾部
24 }
25 }
26 reverse(result.begin(),result.end());//逆置
27 return result;
28 }
4、leetcode 第105题 根据一棵树的前序遍历与中序遍历构造二叉树
1 /**
2 * Definition for a binary tree node.
3 * struct TreeNode {
4 * int val;
5 * TreeNode *left;
6 * TreeNode *right;
7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
8 * };
9 */
10 //通过前序确定根节点 然后通过中序划分左子树具有的元素 右子树具有的元素 然后递归
11 class Solution {
12 public:
13 TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
14 if(preorder.empty())return NULL;
15 return buildTreeHelper(preorder,inorder,0,preorder.size()-1,0,inorder.size()-1);
16 }
17 TreeNode* buildTreeHelper(vector<int>& preorder, vector<int>& inorder,int ps,int pe,int is,int ie)
18 {
19 //ps pe分别为 preorder 的第一个元素的下标和最后一个元素的下标
20 //is ie分别为 inorder 的第一个元素的下标和最后一个元素的下标
21
22 TreeNode* node=new TreeNode(preorder[ps]);
23 int cut;//中根序 根节点所在的地方
24 for(cut=is;cut<ie&&inorder[cut]!=preorder[ps];cut++);//找到分割点
25 int l_len=cut-is;//左子树长度
26 int r_len=ie-cut;//右子树长度
27
28 // cout<<cut<<" "<<l_len<<" "<<r_len<<" "<<endl;
29 // print_vector(preorder,ps+1,ps+l_len);//先根序序列 左子树的部分
30 // print_vector(inorder,is,is+l_len-1);//中根序序列 左子树的部分
31 // print_vector(preorder,pe-r_len+1,pe);//先根序序列 右子树的部分
32 // print_vector(inorder,ie-r_len+1,ie);//中根序序列 右子树的部分
33
34 if(l_len) //若存在左子树 则对左子树进行递归
35 node->left=buildTreeHelper(preorder,inorder,ps+1,ps+l_len,is,is+l_len-1);
36 else
37 node->left=NULL;
38 if(r_len) //若存在右子树 则对右子树进行递归
39 node->right=buildTreeHelper(preorder,inorder,pe-r_len+1,pe,ie-r_len+1,ie);
40 else
41 node->right=NULL;
42 return node;
43 }
44 // void print_vector(vector<int>& v,int s,int e)
45 // {
46 // int i=s;
47 // for(;i<=e;i++)
48 // cout<<v[i]<<" ";
49 // cout<<endl;
50 // }
51 };
5、leetcode 第106题 根据一棵树的中序遍历与后序遍历构造二叉树
1 /**
2 * Definition for a binary tree node.
3 * struct TreeNode {
4 * int val;
5 * TreeNode *left;
6 * TreeNode *right;
7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
8 * };
9 */
10 //类似 先序与中序建立二叉树
11 //后序遍历列表最后一个节点为根节点
12 //在中序中 根节点前的是左子树(is,is+l_len-1) 根节点右边的是右子树(ie-r_len+1,ie)
13 //在后序中 (pe-1-r_len+1,pe-1)为右子树,(ps,ps+l_len-1)为左子树
14 class Solution {
15 public:
16 TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
17 if(postorder.empty())return NULL;
18 return buildTreeHelper(inorder,postorder,0,inorder.size()-1,0,postorder.size()-1);
19 }
20 TreeNode* buildTreeHelper(vector<int>& inorder, vector<int>& postorder,int is,int ie,int ps,int pe)
21 {
22 //is ie分别为 inorder 的第一个元素的下标和最后一个元素的下标
23 //ps pe分别为 postorder 的第一个元素的下标和最后一个元素的下标
24
25 TreeNode* node=new TreeNode(postorder[pe]);
26 int cut;//中根序 根节点所在的地方
27 for(cut=is;cut<ie&&inorder[cut]!=postorder[pe];cut++);//找到分割点
28 int l_len=cut-is;//左子树长度
29 int r_len=ie-cut;//右子树长度
30
31 // cout<<cut<<" "<<l_len<<" "<<r_len<<" "<<endl;
32 // print_vector(postorder,ps,ps+l_len-1);//后根序序列 左子树的部分
33 // print_vector(inorder,is,is+l_len-1);//中根序序列 左子树的部分
34 // print_vector(postorder,pe-r_len,pe-1);//后根序序列 右子树的部分
35 // print_vector(inorder,ie-r_len+1,ie);//中根序序列 右子树的部分
36
37 if(l_len) //若存在左子树 则对左子树进行递归
38 node->left=buildTreeHelper(inorder,postorder,is,is+l_len-1,ps,ps+l_len-1);
39 else
40 node->left=NULL;
41 if(r_len) //若存在右子树 则对右子树进行递归
42 node->right=buildTreeHelper(inorder,postorder,ie-r_len+1,ie,pe-r_len,pe-1);
43 else
44 node->right=NULL;
45 return node;
46 }
47 // void print_vector(vector<int>& v,int s,int e)
48 // {
49 // int i=s;
50 // for(;i<=e;i++)
51 // cout<<v[i]<<" ";
52 // cout<<endl;
53 // }
54 };
6、leetcode 第958题 二叉树完全性检验
1 /**
2 * Definition for a binary tree node.
3 * struct TreeNode {
4 * int val;
5 * TreeNode *left;
6 * TreeNode *right;
7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
8 * };
9 */
10 //层次遍历 若出现空节点 则此节点之后不能再出现非空节点 否则不是完全二叉树
11 class Solution {
12 public:
13 bool isCompleteTree(TreeNode* root) {
14 TreeNode* queue[200],*p;
15 int rear=-1,front=-1;
16 queue[++rear]=root;
17 while(front<rear)
18 {
19 p=queue[++front];
20 if(p)//若节点非空 入队
21 {
22 queue[++rear]=p->left;
23 queue[++rear]=p->right;
24 }
25 else//若节点为空 则判别队列中是否有非空节点 有则不是完全二叉树
26 {
27 while(front<rear)
28 {
29 p=queue[++front];
30 if(p) return false;
31 }
32 }
33 }
34 return true;
35 }
36 };
7、递归统计二叉树的叶子节点数、双分支节点数、单分支节点数、所有节点数
1 class Solution {
2 public:
3 //递归统计所有节点
4 int countNodes(TreeNode* root) {
5 if(root==NULL) return 0;//如果节点为空
6 else if(root->left||root->right) return countNodes(root->left)+countNodes(root->right)+1;//如果存在左子树或右子树
7 else return 1;//如果不存在左右子树
8 }
9 //递归统计所有双分支节点
10 int countNodes(TreeNode* root) {
11 if(root==NULL) return 0;//如果节点为空
12 else if(root->left&&root->right) return countNodes(root->left)+countNodes(root->right)+1;//如果存在左子树右子树
13 else return countNodes(root->left)+countNodes(root->right);//如果不同时存在左右子树
14 }
15 //递归统计所有单分支节点
16 int countNodes(TreeNode* root) {
17 if(root==NULL) return 0;//如果节点为空
18 else if((root->left&&!root->right)||(!root->left&&root->right))
19 return countNodes(root->left)+countNodes(root->right)+1;//如果左右子树不同时存在
20 else return countNodes(root->left)+countNodes(root->right);//如果不存在左右子树或同时存在左右子树
21 }
22 //递归统计所有叶子节点
23 int countNodes(TreeNode* root) {
24 if(root==NULL) return 0;//如果节点为空
25 else if(!root->left&&!root->right) return 1;//如果节点没有孩子
26 else return countNodes(root->left)+countNodes(root->right);//如果节点有孩子
27 }
28 };
8、leetcode 第226题 翻转二叉树
1 /**
2 * Definition for a binary tree node.
3 * struct TreeNode {
4 * int val;
5 * TreeNode *left;
6 * TreeNode *right;
7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
8 * };
9 */
10 class Solution {
11 public:
12 TreeNode* invertTree(TreeNode* root) {
13 if(!root) return NULL;
14 TreeNode* temp=root->left;
15 root->left=invertTree(root->right);//左孩子等于递归交换的右子树
16 root->right=invertTree(temp);//右孩子等于递归交换的左子树
17 return root;
18 }
19 };