标签:nod start 兄弟节点 roo iostream input == 完全二叉树 down
这篇文章是关于PAT的一个总复习,整理以备复习参考。
链表题目中总是会出现地址的保存,如:地址,data,下一个地址
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
A1074 Reversing Linked List 是对要求对链表进行反转;A1032 Sharing要找到一个相同地址的符号;类似还有A1052Linked List Sorting,A1097Deduplication on a Linked List
解决这类问题,就建立两个vector,一个用于暂存数据 ,一个用于最后的答案数据保存。
A1133:小于0的放到最前,介于0~k的依次后放,其余的再依次后放模板案例如下:
#include?<iostream>
#include?<vector>
using?namespace?std;
struct?node{
????int?id,data,next;
}a[100005];
int?main(){
????int?begin,n,k,s,d,e;
????cin>>begin>>n>>k;
????vector<node>?v,ans;
????for(int?i=0;i<n;++i){
????????scanf("%d%d%d",&s,&d,&e);
????????a[s]={s,d,e};
????}
????for(;begin!=-1;begin=a[begin].next){
????????v.push_back(a[begin]);
????}
????for(int?i=0;i<v.size();++i){
????????if(v[i].data<0)?ans.push_back(v[i]);
????}
????for(int?i=0;i<v.size();++i){
????????if(v[i].data>=0&&v[i].data<=k)?ans.push_back(v[i]);
????}
????for(int?i=0;i<v.size();++i){
????????if(v[i].data>k)?ans.push_back(v[i]);
????}
????for(int?i=0;i<ans.size();++i){
????????if(i!=ans.size()-1)?printf("%05d?%d?%05d\n",ans[i].id,ans[i].data,ans[i+1].id);
????????else?printf("%05d?%d?-1",ans[i].id,ans[i].data);
????}
????return?0;
}
struct node{
int data;
node *lchild,*rchild;
};
int pre[maxn],in[maxn];
node*build(int preL,int preR,int inL,int inR){
if(preL>preR) return NULL;
node*root=new node;
root->data=pre[preL];
int k;
for(k=inL;k<=inR;++k){
if(in[k]==pre[preL]) break;
}
int numLeft=k-inL;
root->lchild=build(preL+1,preL+numLeft,inL,k-1);
root->rchild=build(preL+numLeft+1,preR,k+1,inR);
return root;
}
struct node{
int data;
node *lchild,*rchild;
};
int post[maxn],in[maxn];
node*build(int postL,int postR,int inL,int inR){
if(postL>postR) return;
node*root=new node;
root->data=post[postR];
int k;
for(k=inL;k<=inR;++k){
if(in[k]==post[postR]) break;
}
int numLeft=k-inL;
root->lchild=build(postL,postL+numLeft-1,inL,k-1);
root->rchild=build(postL+numLeft,postR-1,k+1,inR);
return root;
}
struct node{
int data;
node *lchild,*rchild;
};
int level[maxn],in[maxn];
node*build(int levelL,int levelR,int inL,int inR){
if(inL>inR) return NULL;
int k,flag=0;
while(levelL<=levelR){
for(k=inL;k<=inR;++k){
if(in[k]==level[levelL]){
flag=1;
break;
}
}
if(flag) break;
++levelL;
}
node*root=new node;
root->data=in[k];
root->lchild=build(levelL+1,levelR,inL,k-1);
root->rchild=build(levelL+1,levelR,k+1,inR);
}
参见A119
#include <iostream>
#include <vector>
using namespace std;
vector<int> in,pre,post;
bool flag=true;
void getIn(int prel,int prer,int postl,int postr){
if(prel==prer){
in.push_back(pre[prel]);
return;
}
if(pre[prel]==post[postr]){
int i=prel+1;
while(i<prer&&pre[i]!=post[postr-1]) ++i;
if(i-prel>1){
getIn(prel+1,i-1,postl,postl+(i-prel-1)-1);
}else flag=false;
in.push_back(post[postr]);
getIn(i,prer,postl+(i-prel-1),postr-1);
}
}
int main(){
int n;
cin>>n;
pre.resize(n),post.resize(n);
for(int i=0;i<n;++i) cin>>pre[i];
for(int i=0;i<n;++i) cin>>post[i];
getIn(0,n-1,0,n-1);
printf("%s\n%d",flag==true?"Yes":"No",in[0]);
for(int i=1;i<in.size();++i) printf(" %d",in[i]);
printf("\n");
return 0;
}
??很多的题目中构建的二叉树需要很多信息,比如一个节点的高度、节点的父节点、两个节点是不是兄弟节点、甚至一个二叉树是不是完全二叉树。
19年春季考试第四题详细考察了这一问题
我们采用静态二叉树的存储实现:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
const int maxn=1000;
struct node{
int layer;
int left,right,parent;
};
node btree[maxn];
int root;
bool isFullTree=true;
int n,m;
int post[maxn],in[maxn];
void inputData(){
cin>>n;
for(int i=0;i<n;++i) scanf("%d",post+i);
for(int i=0;i<n;++i) scanf("%d",in+i);
}
int mfind(int start,int end,int key){
for(int i=start;i<=end;++i){
if(in[i]==key) return i;
}
return -1;
}
int create(int parent,int pl,int pr,int inl,int inr){
if(inl>inr) return -1;
int key=post[pr];
int mid=mfind(inl,inr,key);
if(parent==-1){
btree[key].layer=0;
root=key;
}else{
btree[key].parent=parent;
btree[key].layer=btree[parent].layer+1;
}
btree[key].left=create(key,pl,pl+mid-inl-1,inl,mid-1);
btree[key].right=create(key,pl+mid-inl,pr-1,mid+1,inr);
if((btree[key].left==-1&&btree[key].right!=-1)||(btree[key].right==-1&&btree[key].left!=-1)){
isFullTree=false;
}
return key;
}
int main(){
inputData();
create(-1,0,n-1,0,n-1);
string comm;
int a,b;
bool flag=true;
cin>>m;
getchar();
for(int i=0;i<m;++i){
getline(cin,comm);
if(comm.find("root")!=-1){
sscanf(comm.c_str(),"%d is the root",&a);
flag=(root==a);
}else if(comm.find("siblings")!=-1){
sscanf(comm.c_str(),"%d and %d are siblings",&a,&b);
flag=(btree[a].parent==btree[b].parent);
}else if(comm.find("parent")!=-1){
sscanf(comm.c_str(),"%d is the parent of %d",&a,&b);
flag=(a==btree[b].parent);
}else if(comm.find("left")!=-1){
sscanf(comm.c_str(),"%d is the left child of %d",&a,&b);
flag=(a==btree[b].left);
}else if(comm.find("right")!=-1){
sscanf(comm.c_str(),"%d is the right child of %d",&a,&b);
flag=(a==btree[b].right);
}else if(comm.find("level")!=-1){
sscanf(comm.c_str(),"%d and %d are on the same level",&a,&b);
flag=(btree[a].layer==btree[b].layer);
}else if(comm.find("full")!=-1){
flag=isFullTree;
}
if(flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}
希望大家千万千万不要小看二叉树的静态存储结构,不要盲目相信指针是最好的。共勉!????????
AVL树的构建也比较重要,重点的地方在于插入的时候的平衡要记住。
struct node{
int v,height;
node *lchild,*rchild;
};
node*newNode(int v){
node*root=new node;
root->v=v;
root->height=1;
root->lchild=root->rchild=NULL;
return root;
}
int getHeight(node*root){
if(root==NULL) return 0;
return root->height;
}
int getBalanceFactor(node*root){
return getHeight(root->lchild)-getHeight(root->rchild);
}
void updateHeight(node*root){
root->height=max(getHeight(root->lchild),getHeight(root->rchild))+1;
}
void L(node*&root){
node*temp=root->rchild;
root->rchild=temp->lchild;
temp->lchild=root;
updateHeight(root);
updateHeight(temp);
root=temp;
}
void R(node*&root){
node*temp=root->lchild;
root->lchild=temp->rchild;
temp->rchild=root;
updateHeight(root);
updateHeight(temp);
root=temp;
}
void insert(node*&root,int v){
if(root==NULL){
root=newNode(v);
return;
}
if(v<root->v){
insert(root->lchild,v);
updateHeight(root);
if(getBalanceFactor(root)==2){
if(getBalanceFactor(root->lchild)==1){
R(root);
}else if(getBalanceFactor(root->lchild)==-1){
L(root->lchild);
R(root);
}
}
}else{
insert(root->rchild,v);
updateHeight(root);
if(getBalanceFactor(root)==-2){
if(getBalanceFactor(root->right)==-1){
L(root);
}else if(getBalanceFactor(root->right)==1){
R(root->left);
L(root);
}
}
}
}
node*create(int data[],int n){
node*root=NULL;
for(int i=0;i<n;++i){
insert(root,data[i]);
}
return root;
}
堆是完全二叉树
int heap[maxn],n=10;
void downAdjust(int low,int high){//自顶向下
int i=low,j=2*i;
while(j<=high){//有孩子节点
if(j+1<=high&&heap[j+1]>heap[j]){//右孩子存在,且大于左孩子,则j指向右孩子
++j;
}
if(heap[j]>heap[i]){//如果孩子比父亲节点大,则交换
swap(heap[j],heap[i]);
i=j;
j=2*i;
}else break;//如果小,则结束
}
}
void create(){//建堆
for(int i=n/2;i>=1;--i){
downAdjust(i,n);
}
}
void heapSort(){//堆排序
create();
for(int i=n;i>1;--i){
swap(heap[i],heap[1]);
downAdjust(1,i-1);
}
}
void deleteTop(){//删除堆顶元素
heap[1]=heap[n--];
downAdjust(1,n);
}
void upAdjust(int low,int high){//自底向上是插入
int i=high,j=i/2;
while(j>=low){
if(heap[j]<heap[i]){
swap(heap[j],heap[i]);
i=j;
j=i/2;
}else break;
}
}
void insert(int x){
heap[++n]=x;
upAdjust(1,n);
}
标签:nod start 兄弟节点 roo iostream input == 完全二叉树 down
原文地址:https://www.cnblogs.com/sszz/p/13584558.html