TZOJ 数据结构期末历年题目
A.数据结构练习题――线性表操作
线性表的基本操作
1.在某个位置p插入val,复杂度O(p)
2.在某个位置p删除val,复杂度O(p)
3.查找某个位置p的值,复杂度O(p)
4.清除链表,复杂度O(链表长)
1 #include<iostream> 2 #include<string> 3 #include<list> 4 using namespace std; 5 int main() 6 { 7 int n,p,x; 8 string s; 9 list<int>li; 10 list<int>::iterator it; 11 while(cin>>s) 12 { 13 if(s=="exit")break; 14 else if(s=="clear")li.clear(); 15 else if(s=="insert") 16 { 17 cin>>n; 18 for(int i=0;i<n;i++) 19 { 20 cin>>p>>x; 21 it=li.begin(); 22 while(--p)it++; 23 li.insert(it,x); 24 } 25 } 26 else 27 { 28 cin>>p; 29 it=li.begin(); 30 while(--p)it++; 31 cout<<*it<<endl; 32 if(s=="delete")li.erase(it); 33 } 34 } 35 return 0; 36 }
B.数据结构练习题――合并表
线性表的基本操作
先把第一排每个数放入链表,然后把b中的每个数插入链表,复杂度O(n+m)
1 #include<iostream> 2 #include<list> 3 using namespace std; 4 int main() 5 { 6 int t,n,m; 7 list<int>li; 8 list<int>::iterator it; 9 cin>>t; 10 while(t--) 11 { 12 li.clear(); 13 cin>>n; 14 for(int i=0,a;i<n;i++)cin>>a,li.push_back(a); 15 cin>>m; 16 it=li.begin(); 17 for(int i=0,b;i<m;i++) 18 { 19 cin>>b; 20 while(it!=li.end()&&*it<=b)it++; 21 li.insert(it,b); 22 } 23 cout<<n+m; 24 for(auto X:li) 25 cout<<" "<<X; 26 cout<<endl; 27 } 28 return 0; 29 }
C.数据结构―线性表插入删除
线性表的基本操作
1.在第pos个位置前插入连续m个数,由于是插入在前面,所以找到第pos个位置的地址it,然后不断插入,复杂度O(m)
2.删除第pos个位置开始连续m个数,若到表尾则删除到结尾,这里erase第pos个位置的地址it后,需要讲,复杂度O(m)
1 #include<stdio.h> 2 #include<list> 3 using namespace std; 4 int main() 5 { 6 int t,n,p,pos,m,x; 7 char s[10]; 8 scanf("%d",&t); 9 while(t--) 10 { 11 list<int>l; 12 list<int>::iterator it; 13 scanf("%d",&n); 14 for(int i=0;i<n;i++) 15 scanf("%d",&x),l.push_back(x); 16 scanf("%d",&p); 17 for(int i=0;i<p;i++) 18 { 19 scanf("%s",s); 20 if(s[0]=='i') 21 { 22 scanf("%d%d",&pos,&m); 23 it=l.begin(); 24 while(--pos>0)it++;//这里>0考虑到pos=0的情况 25 while(m--) 26 scanf("%d",&x),l.insert(it,x); 27 } 28 if(s[0]=='d') 29 { 30 scanf("%d%d",&pos,&m); 31 it=l.begin(); 32 while(--pos)it++; 33 while(m--&&it!=l.end())l.erase(it++); 34 } 35 } 36 int k=0; 37 for(it=l.begin();it!=l.end();it++) 38 { 39 if(k++)printf(" "); 40 printf("%d",*it); 41 } 42 printf("\n"); 43 } 44 return 0; 45 }
E.数据结构练习题――栈
栈的基本操作
1.把元素val压入栈,复杂度O(1)
2.弹出栈顶元素,若栈为空输出None,否则输出栈顶元素val,复杂度O(1)
3.输出栈顶元素,若栈为空输出None,否则输出栈顶元素val,复杂度O(1)
4.清空栈,复杂度O(栈中元素数)
1 #include<iostream> 2 #include<string> 3 #include<stack> 4 using namespace std; 5 int main() 6 { 7 int a; 8 string s; 9 stack<int>st; 10 while(cin>>s) 11 { 12 if(s=="exit")break; 13 if(s=="push")cin>>a,st.push(a); 14 if(s=="top") 15 { 16 if(st.empty())cout<<"None"<<endl; 17 else cout<<st.top()<<endl; 18 } 19 if(s=="pop") 20 { 21 if(st.empty())cout<<"None"<<endl; 22 else cout<<st.top()<<endl,st.pop(); 23 } 24 if(s=="clear") 25 while(!st.empty())st.pop(); 26 } 27 return 0; 28 }
F.数据结构练习题----队列的基本操作
队列基本操作
1.值val入队,复杂度O(1)
2.出队,若队列为空,输出None,否则输出队头元素val,复杂度O(1)
3.输出队列中所有元素,若队列为空,输出None,否则输出所有元素,需要借助一个临时队列p用于存输出前的队列,复杂度O(原队列长)
1 #include<iostream> 2 #include<queue> 3 #include<string> 4 using namespace std; 5 int main() 6 { 7 int a; 8 string s; 9 queue<int>q,p; 10 while(cin>>s) 11 { 12 if(s=="exit")break; 13 if(s=="enq")cin>>a,q.push(a); 14 if(s=="printq") 15 { 16 if(q.empty()){cout<<"None"<<endl;continue;} 17 int k=0; 18 p=q; 19 while(!q.empty()) 20 { 21 if(k++)cout<<" "; 22 cout<<q.front(),q.pop(); 23 } 24 cout<<endl; 25 q=p; 26 } 27 if(s=="deq") 28 { 29 if(q.empty())cout<<"None"<<endl; 30 else cout<<q.front()<<endl,q.pop(); 31 } 32 } 33 return 0; 34 }
G.简单排序
给你n个数让你排个序,复杂度O(nlogn)
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 int main() 5 { 6 int t,n,a[1005]; 7 cin>>t; 8 while(t--) 9 { 10 cin>>n; 11 for(int i=0;i<n;i++)cin>>a[i]; 12 sort(a,a+n); 13 for(int i=0;i<n;i++)cout<<a[i]<<(i==n-1?"\n":" "); 14 } 15 return 0; 16 }
H.快速排序
给你n个数让你排序,注意用C++提交,复杂度O(nlogn)
1 #include<stdio.h> 2 #include<algorithm> 3 using namespace std; 4 int main() 5 { 6 int t,n,a[100005]; 7 while(scanf("%d",&n)!=EOF) 8 { 9 for(int i=0;i<n;i++)scanf("%d",&a[i]); 10 sort(a,a+n); 11 for(int i=0;i<n;i++)printf("%d%c",a[i],i==n-1?'\n':' '); 12 } 13 return 0; 14 }
I.二分查找
二分查找,注意C++提交,复杂度O(logn)
lowber_bound(a,a+n,x);
函数的作用是返回>=x的第一个位置,若没有返回最后一个位置
第一个为二分开始的位置,第二个为二分结束的位置,注意左闭右开,第三个为查找的值val
1 #include<stdio.h> 2 #include<algorithm> 3 using namespace std; 4 int a[1000005]; 5 int main() 6 { 7 int n,m; 8 while(scanf("%d",&n)!=EOF) 9 { 10 for(int i=0;i<n;i++)scanf("%d",&a[i]); 11 scanf("%d",&m); 12 int pos=lower_bound(a,a+n,m)-a; 13 if(pos==n||a[pos]!=m)printf("None\n"); 14 else printf("%d\n",pos+1); 15 } 16 return 0; 17 }
J.图的遍历
图的深度优先和图的广度优先,需要有一个基本的认识,复杂度O(2n)
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 int n,m,vis[35],G[35][35]; 6 void dfs(int u) 7 { 8 if(vis[u])return; 9 printf("%d ",u); 10 vis[u]=1; 11 for(int i=1;i<=n;i++)if(!vis[i]&&G[u][i])dfs(i); 12 } 13 void bfs(int u) 14 { 15 queue<int>q; 16 q.push(u); 17 while(!q.empty()) 18 { 19 u=q.front();q.pop(); 20 if(vis[u])continue; 21 printf("%d ",u); 22 vis[u]=1; 23 for(int i=1;i<=n;i++)if(!vis[i]&&G[u][i])q.push(i); 24 } 25 } 26 int main() 27 { 28 while(scanf("%d%d",&n,&m)!=EOF) 29 { 30 memset(G,0,sizeof(G)); 31 for(int i=0,u,v;i<m;i++) 32 { 33 scanf("%d%d",&u,&v); 34 G[u][v]=G[v][u]=1; 35 } 36 memset(vis,0,sizeof(vis)); 37 for(int i=1;i<=n;i++)if(!vis[i])dfs(i); 38 printf("\n"); 39 memset(vis,0,sizeof(vis)); 40 for(int i=1;i<=n;i++)if(!vis[i])bfs(i); 41 printf("\n"); 42 } 43 return 0; 44 }
K.二叉树遍历
这题给你的是层序,而且只有1000个节点,我们知道2^10-1=1024,所以最多10层,我们可以用数组建树
然后你需要知道如何先序中序后序,复杂度O(3*k),k为节点数
1 #include<stdio.h> 2 int a[1005],k; 3 void P(int u,int flag) 4 { 5 if(u>k||a[u]==0)return; 6 if(flag==1)printf(" %d",a[u]);//先序 7 P(u*2,flag);//左儿子 8 if(flag==2)printf(" %d",a[u]);//中序 9 P(u*2+1,flag);//右儿子 10 if(flag==3)printf(" %d",a[u]);//后序 11 } 12 int main() 13 { 14 int t,x; 15 scanf("%d",&t); 16 while(t--) 17 { 18 k=1; 19 while(scanf("%d",&x),x!=-1)a[k++]=x; 20 for(int i=1;i<=3;i++) 21 P(1,i),printf("\n"); 22 } 23 return 0; 24 }