数据结构

基本数据结构


 链表

数组与链表的不同之处
数组:支持随机访问,不支持在任意位置插入或删除元素
链表:支持在随机位置插入或删除,但只能按顺序访问
用struct来表示链表的节点,为了避免在左右两端或者在空链表中访问越界,就新建head和tail节点来表示链头和链尾,在这两个几点之间储存实际节点。(以此来减少对于边界的判断)
以下是双链表的代码实现

定义

1 struct Node{
2     int value;
3     int prev,next;
4 }node[SIZE];
5 int head,tail,tot;

建表

1 void initialize(){
2     tot=2;
3     head=1,tail=2;
4     node[head].next=tail;
5     node[tail].prev=head;
6 }

在节点x后插入包含数值v的新节点

1 void insert(int x,int v){
2     xx=tot++;
3     node[xx].value=v;//v是xx的值 
4     node[node[x].next].prev=xx;//x后面的那个数的前面应该是xx 
5     node[xx].next=node[x].next;//xx的后边应该是x的后面 
6     node[x].next=xx;//x的后面一个是xx 
7     node[xx].prev=x;//xx的前面是x 
8 }

删除节点x

1 void remove(int x){
2     node[node[x].prev].next=node[x].next;
3     node[node[x].next].prev=node[x].prev;
4 } 

清空链表

1 void clear(){
2     memset(node,0,sizeof(node));
3     head=tail=tot=0;
4 }

 

后进先出

1 int stack[N], top=0;//top表示栈顶 
2 void push(int a){stack[top++]=a;}//入栈 
3 int pop(){return stack[--top];}//出栈 
4 bool empty(){return top<0;}//判断栈是否是空栈 

 队列

先进先出

1 int queue[N],front=0,rear=0;//front队首元素,rear队尾元素右侧 
2 void push(int a){queue[rear++]=a;}
3 int pop(){return queue[front++];}
4 bool empty(){return front==rear;}

单调队列

啊啊啊啊,终于学了呢,之前dp的坑也可以填了呢。即是保证它是一个单调递增或递减的队列,若检测到读入的这个数比它队列前面的那个数生存能力强,就把前面的数从队尾挤掉,自己填进去。若比前数生存能力弱,就可以把这个数push进队尾,毕竟它的出现时间较晚。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e6+10;
 4 int a[N],n,m,f,i,j,s_min[N],s_max[N];
 5 deque<int> x,y;//x小y大 
 6 int main(){
 7     cin>>n>>m;
 8     for(int i=1;i<=n;i++)cin>>a[i];
 9     x.push_front(1);
10     y.push_front(1);
11     s_min[1]=1;
12     s_max[1]=1;
13     m--;
14     for(int i=2;i<=n;i++){
15         while (x.size() && x.front()+m<i)
16             x.pop_front();
17         while (y.size() && y.front()+m<i)
18             y.pop_front();
19 
20         while (x.size() && a[x.back()]>=a[i])
21             x.pop_back();
22         while (y.size() && a[y.back()]<=a[i])
23             y.pop_back();
24             x.push_back(i);
25             y.push_back(i);
26 
27         s_min[i]=x.front();
28         s_max[i]=y.front();
29     }
30     for(int i=m+1;i<=n;i++)
31         cout<<a[s_min[i]]<<" ";
32     cout<<endl;
33     for(int i=m+1;i<=n;i++)
34         cout<<a[s_max[i]]<<" ";
35     return 0;
36 }

 


 

 二叉树

用链表储存二叉树,lson表示左儿子,rson表示右儿子。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,flag[100009],nn;
 4 struct Node{
 5     int num,lson,rson;
 6 }node[100009];
 7 int tot=0;
 8 void qdfs(int x){//前序遍历 
 9     if(x==0) return;
10     cout<<x<<" ";
11     qdfs(node[x].lson);
12     qdfs(node[x].rson);
13 }
14 void z(int x){//中序遍历 
15     if(x==0) return;
16     z(node[x].lson);
17     cout<<x<<" ";
18     z(node[x].rson);
19 }
20 void h(int x){//后序遍历 
21     if(x==0) return;
22     h(node[x].lson);
23     h(node[x].rson);
24     cout<<x<<" ";
25 }
26 int main(){
27     cin>>n;
28     for(int i=1;i<=n;i++){
29         int f,l,r;
30         cin>>f>>l>>r;
31         node[f].lson=l;
32         node[f].rson=r;
33         flag[l]=1,flag[r]=1;
34     }//二叉树储存
35     for(int i=1;i<=n;i++) if(flag[i]==0) nn=i;//寻找根节点
36     qdfs(nn);
37     cout<<endl;z(nn);cout<<endl;h(nn);
38     return 0;
39 } 

还有一种神奇的(当然也有点慢)做法(只针对前序遍历

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,le[27],ri[27];
 4 char f;
 5 void dfs(int x){
 6     cout<<char(x+'a');
 7     if(le[x]!=-1) dfs(le[x]);
 8     if(ri[x]!=-1) dfs(ri[x]);
 9 }
10 int main(){
11     cin>>n;
12     for(int i=1;i<=n;i++){
13         char x,y,z;
14         cin>>x>>y>>z;
15         if(i==1) f=x;
16         if(y=='*') le[x-'a']=-1;
17         else le[x-'a']=y-'a';
18         if(z=='*') ri[x-'a']=-1;
19         else ri[x-'a']=z-'a';
20     }
21     dfs(f-'a');
22     return 0;
23 }

 并查集

这就是“附庸的附庸依旧是我的附庸”bushi

1 for(int i=1;i<=n;i++) fa[i]=i;//初始化 
2 int get(int x){//找最大统领 
3     if(x==fa[x]) return x;
4     return fa[x]=get(fa[x]);
5 }
6 void merge(int x,int y){//合并 
7     fa[get(x)]=get(y);
8 }

贴一道

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int size[30001],d[30001],fa[30001];
 4 int get(int x){
 5     if(x==fa[x]) return x;
 6     int root=get(fa[x]);
 7     d[x]+=d[fa[x]];
 8     return fa[x]=root;
 9 }
10 void merge(int x,int y){
11     x=get(x),y=get(y);
12     fa[x]=y,d[x]=size[y];
13     size[y]+=size[x];
14 }
15 int main(){
16     for(int i=1;i<=30001;i++){
17         size[i]=1;
18         fa[i]=i;
19     }
20     int t;
21     cin>>t;
22     for(int i=1;i<=t;i++){
23         char a;
24         int x,y;
25         cin>>a>>x>>y;
26         if(a=='M') merge(x,y);
27         else{
28             if(get(x)!=get(y)) cout<<-1<<endl;
29             else{
30                 if(d[x]>d[y]) cout<<d[x]-d[y]-1<<endl;
31                 else cout<<d[y]-d[x]-1<<endl;
32             }
33         }
34     }
35     return 0;
36 }

后记:期待今晚的可乐(虽然是无糖的,但是还是很喜欢的呢 ps.没有糖就没有灵魂了

posted @ 2020-10-21 21:04  001A  阅读(126)  评论(0编辑  收藏  举报