1 重要变量定义说明
1.1 node类型和a数组;
创建了node类型的变量,并开了node类型的数组。因为n的范围是3×10^5,比较大,所以解题策略是按照输入顺序存储,下标从1开始,每个元素的left和right初始化为0。之后通过比较节点val的大小,left存储该节点左孩子的数组下标,right存储右孩子的数组下标。
struct node{
int val;
int left;
int right;
node(){ }
node(int v,int l,int r):val(v),left(l),right(r){ }
}a[300010];
样例数据按照上述方式的存储如下:
下标 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
val | 1 | 4 | 3 | 9 | 10 | 35 | 2 | 7 |
left | 0 | 3 | 7 | 0 | 0 | 0 | 0 | 0 |
right | 2 | 4 | 0 | 5 | 6 | 0 | 0 | 0 |
1.2 dm
存储树的深度
1.3 栈stk
本题使用非递归的方式实现后续遍历,从根节点开始,用栈存储后序遍历还没输出的节点的下标。
1.4 vis数组
用非递归后序遍历时,要避免a数组的元素多次入栈的问题,因此用vis数组标记元素是否入过栈。
2 二叉搜索树的构建
void build(){
int dm=1,v;
for(int i=1;i<=n;i++){
cin>>v;
a[i] = node(v,0,0);
int j=1;
if(i!=1){
j=1;
int d=2;
while(1){
if(a[j].val<a[i].val){
if(a[j].right!=0){
j=a[j].right;
d++;
}
else{
a[j].right = i;
break;
}
}
else if(a[j].val>a[i].val){
if(a[j].left!=0){
j=a[j].left;
d++;
}
else{
a[j].left = i;
break;
}
}
}
dm = max(dm,d);
}
}
cout<<"deep="<<dm<<endl;
}
3 二叉树的后序遍历
后序遍历是左-右-根,入栈顺序是根-右-左(因为栈是后进先出),当节点没有左孩子和右孩子时,就输出栈顶节点的值,并让该节点出栈,一直做直到栈空为止。
void traverse(){
stack<int> stk;
stk.push(1);
vis[1]=1;
int tp = stk.top();
while(stk.empty()==0){
tp = stk.top();
bool ps=0;
if(a[tp].right!=0&&vis[a[tp].right]==0){
stk.push(a[tp].right);
vis[a[tp].right]=1;
ps=1;
}
if(a[tp].left!=0&&vis[a[tp].left]==0){
stk.push(a[tp].left);
vis[a[tp].left]=1;
ps=1;
}
if(ps==0){
cout<<a[tp].val<<endl;
stk.pop();
}
}
}
4 AC代码
#include<bits/stdc++.h>
using namespace std;
struct node{
int val;
int left;
int right;
node(){ }
node(int v,int l,int r):val(v),left(l),right(r){ }
}a[300010];
bool vis[300010];
int n;
void build(){
int dm=1,v;
for(int i=1;i<=n;i++){
cin>>v;
a[i] = node(v,0,0);
int j=1;
if(i!=1){
j=1;
int d=2;
while(1){
if(a[j].val<a[i].val){
if(a[j].right!=0){
j=a[j].right;
d++;
}
else{
a[j].right = i;
break;
}
}
else if(a[j].val>a[i].val){
if(a[j].left!=0){
j=a[j].left;
d++;
}
else{
a[j].left = i;
break;
}
}
}
dm = max(dm,d);
}
}
cout<<"deep="<<dm<<endl;
}
void traverse(){
stack<int> stk;
stk.push(1);
vis[1]=1;
int tp = stk.top();
while(stk.empty()==0){
tp = stk.top();
bool ps=0;
if(a[tp].right!=0&&vis[a[tp].right]==0){
stk.push(a[tp].right);
vis[a[tp].right]=1;
ps=1;
}
if(a[tp].left!=0&&vis[a[tp].left]==0){
stk.push(a[tp].left);
vis[a[tp].left]=1;
ps=1;
}
if(ps==0){
cout<<a[tp].val<<endl;
stk.pop();
}
}
}
int main(){
cin>>n;
build();
traverse();
return 0;
}