基本資料結構
阿新 • • 發佈:2020-10-21
基本資料結構
連結串列
陣列與連結串列的不同之處
陣列:支援隨機訪問,不支援在任意位置插入或刪除元素
連結串列:支援在隨機位置插入或刪除,但只能按順序訪問
用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 voidpush(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.沒有糖就沒有靈魂了)