提示:庸言之信,庸行之谨 闲邪存其城 ,善世而不伐
前言
提示:这里可以添加本文要记录的大概内容:
建议看这些题目之前 先来看一下这一篇基础篇,不看? 不会有好果子吃的
提示:接下来开始我们的正片——扯淡
二叉树的层序遍历(II)
给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
3
输入:root = [3,9,20,null,null,15,7]
输出:[[15,7],[9,20],[3]]
相信大家也看出来了,给我们一个树 我们从下往上层序来遍历这棵树,这里我要问你三个问题 1、普通的从上而下你会了?2、会使用层序创造一棵树了? 3、输出是否会按层输出?不会?还是就会一个? 所以还不去看这篇
其实这个题可以这样子 我们之前层序遍历的时候按层输出的时候不是得到一个 [3] [[9][20]] [[15][7]] 这里需要的结果是 [[15][7]] [[9][20]] [3] 这里直接使用一个二维向量,反转其中的就可以 或者使用一个栈与向量结合起来一起使用 因为栈是后进先出 使用可以使用栈与向量结合起来一起使用也可以实现反转, 我们可以直接写出代码
二维向量
#include<bits/stdc++.h>
#define ElemType int
using namespace std;
typedef struct BiNTree{
struct BiNTree* Lchild;
ElemType data;
struct BiNTree* Rchild;
}BiNTree;
/*层序的思想是,首先需要判断此时第一个元素是否为空 为此
若是为空就不用需要进入树队中了 若是第一个元素不为空 则进入队列中
然后为其分配左右子树,若是值为-1 则表示此时的孩子为空 不需要入队
若是值不为-1 ,让其作为此时结点的孩子,然后此孩子入队
直到元素值队列为空*/
void Creat(BiNTree* &T){
int val;
BiNTree* cur;//定义一个cur
queue<ElemType> Q;
queue<BiNTree*> TreeQue;
cout<<"请输入层序遍历的序列"<<endl;
while(scanf("%d",&val)!=EOF) Q.push(val);
if(Q.front()==-1){
cout<<"树为空"<<endl;
T=NULL;
return ;
}
else{
T=(BiNTree*)malloc(sizeof(BiNTree));
T->data=Q.front();
TreeQue.push(T);
}
Q.pop();
while(!Q.empty()){//我们每一次处理 处理的都是左右孩子,所以也就需要两个if
cur=TreeQue.front();//取出此时树队中的第一元素
if(Q.front()==-1){//此时这个结点值为NULL
cout<<cur->data<<"左孩子为空"<<endl;
cur->Lchild=NULL;
}
else{//新生成一个树结点用来存放此时的结点信息
cout<<cur->data<<"左孩子为"<<Q.front()<<endl;
cur->Lchild=(BiNTree*)malloc(sizeof(BiNTree)) ;
cur->Lchild->data=Q.front();
TreeQue.push(cur->Lchild);
}
Q.pop();//处理完数据之后需要弹出 来取此结点右子树的值
//上面的if else 是处理结点左孩子 下面我们来处理右孩子
if(Q.front()==-1){
cout<<cur->data<<"右孩子为空"<<endl;;
cur->Rchild=NULL;
}
else{
cout<<cur->data<<"右孩子为"<<Q.front()<<endl;
cur->Rchild=(BiNTree*)malloc(sizeof(BiNTree));
cur->Rchild->data=Q.front();
TreeQue.push(cur->Rchild);
}
Q.pop();
TreeQue.pop();
}
}
vector<vector<int>> LevelOrder(BiNTree* T){//这里我们是使用的是队列来完成这个操作
queue<BiNTree*> Q; BiNTree* cur;
vector<vector<int>> result;
if(T==NULL){//跟前面一样 若是为空则不需要进队 直接返回即可
return result;
}
Q.push(T);
while(!Q.empty()){
vector<int> LevelResult;
int size=Q.size();//需要一个值来保存 因为Q.size 是一直变得
for(int i=0;i<size;i++){
cur=Q.front();
cout<<cur->data<<" ";
LevelResult.push_back(cur->data);
if(cur->Lchild) Q.push(cur->Lchild);
if(cur->Rchild) Q.push(cur->Rchild);
Q.pop();
}
cout<<endl;
result.push_back(LevelResult);
}
reverse(result.begin(),result.end());
cout<<"逆序输出是"<<endl;
for(int i=0;i<result.size();i++){
for(int j=0;j<result[i].size();j++){
cout<<result[i][j]<<" ";
}
cout<<endl;
}
return result;
}
main(){
int i=0;
BiNTree* T=NULL;
vector<vector<int>> result;
Creat(T);
cout<<"此时树的层序遍历是"<<endl;
LevelOrder(T);
}
栈与向量的连用
这里只需要替换一下这个同名函数就可以,就不放完整代码了,占地方
#include<bits/stdc++.h>
#define ElemType int
using namespace std;
typedef struct BiNTree{
struct BiNTree* Lchild;
ElemType data;
struct BiNTree* Rchild;
}BiNTree;
/*层序的思想是,首先需要判断此时第一个元素是否为空 为此
若是为空就不用需要进入树队中了 若是第一个元素不为空 则进入队列中
然后为其分配左右子树,若是值为-1 则表示此时的孩子为空 不需要入队
若是值不为-1 ,让其作为此时结点的孩子,然后此孩子入队
直到元素值队列为空*/
void Creat(BiNTree* &T){
int val;
BiNTree* cur;//定义一个cur
queue<ElemType> Q;
queue<BiNTree*> TreeQue;
cout<<"请输入层序遍历的序列"<<endl;
while(scanf("%d",&val)!=EOF) Q.push(val);
if(Q.front()==-1){
cout<<"树为空"<<endl;
T=NULL;
return ;
}
else{
T=(BiNTree*)malloc(sizeof(BiNTree));
T->data=Q.front();
TreeQue.push(T);
}
Q.pop();
while(!Q.empty()){//我们每一次处理 处理的都是左右孩子,所以也就需要两个if
cur=TreeQue.front();//取出此时树队中的第一元素
if(Q.front()==-1){//此时这个结点值为NULL
cout<<cur->data<<"左孩子为空"<<endl;
cur->Lchild=NULL;
}
else{//新生成一个树结点用来存放此时的结点信息
cout<<cur->data<<"左孩子为"<<Q.front()<<endl;
cur->Lchild=(BiNTree*)malloc(sizeof(BiNTree)) ;
cur->Lchild->data=Q.front();
TreeQue.push(cur->Lchild);
}
Q.pop();//处理完数据之后需要弹出 来取此结点右子树的值
//上面的if else 是处理结点左孩子 下面我们来处理右孩子
if(Q.front()==-1){
cout<<cur->data<<"右孩子为空"<<endl;;
cur->Rchild=NULL;
}
else{
cout<<cur->data<<"右孩子为"<<Q.front()<<endl;
cur->Rchild=(BiNTree*)malloc(sizeof(BiNTree));
cur->Rchild->data=Q.front();
TreeQue.push(cur->Rchild);
}
Q.pop();
TreeQue.pop();
}
}
stack<vector<int>> LevelOrder(BiNTree* T){//这里我们是使用的是队列来完成这个操作
queue<BiNTree*> Q; BiNTree* cur;
stack<vector<int>> result;
if(T==NULL){//跟前面一样 若是为空则不需要进队 直接返回即可
return result;
}
Q.push(T);
while(!Q.empty()){
vector<int> LevelResult;
int size=Q.size();//需要一个值来保存 因为Q.size 是一直变得
for(int i=0;i<size;i++){
cur=Q.front();
cout<<cur->data<<" ";
LevelResult.push_back(cur->data);
if(cur->Lchild) Q.push(cur->Lchild);
if(cur->Rchild) Q.push(cur->Rchild);
Q.pop();
}
//每一次for之后这层的容器收集的结果要放在总的栈中
cout<<endl;
result.push(LevelResult);
}
cout<<"逆序输出是"<<endl;
while(!result.empty()){
vector<int> vec=result.top();
for(int i=0;i<vec.size();i++){
cout<<vec[i]<<" ";
}
cout<<" "<<endl;
result.pop();
}
return result;
}
main(){
int i=0;
BiNTree* T=NULL;
vector<vector<int>> result;
Creat(T);
cout<<"此时树的层序遍历是"<<endl;
LevelOrder(T);
}