csp普及赛数据结构
线性表
单链表 双向链表 循环链表
单链表
概念参考:
https://www.cnblogs.com/myeln/articles/15169093.html
洛谷P1540
https://www.luogu.com.cn/problem/P1540
#include<bits/stdc++.h> using namespace std; int n; int m; //在链表容器中查找指定元素 bool findList(int x, list<int> L){ list<int>::iterator iter;//迭代器实现遍历细节 for(iter=L.begin();iter!=L.end();iter++){ if(*iter == x)//找到返回true return true; } return false; } int main(){ int t; int cnt; while(cin>>m>>n){ cnt = 0; list<int> tempList;//链表结构容器 for(int i=0;i<n;i++){ cin>>t; if(findList(t,tempList)){//如果有了,不统计 continue; }else{ if(tempList.size() == m){//达到最大容量,删除一个 tempList.pop_front(); } tempList.push_back(t);//新的放入链表 cnt++;//新放入累加 } } cout<<cnt<<endl; } }
双向链表
https://www.luogu.com.cn/problem/P1160
C++ STL 底层实现是通过双向链表
#include <bits/stdc++.h> using namespace std; bool vis[100005]; list<int> stus;//int 链表结构 list<int>::iterator pos[100005];//记录链表结构下标 int main(){ int n; scanf("%d",&n); stus.push_back(1);//先将1号同学安排进队列 pos[1] = stus.begin();//是 iterator(相当于指针功能)迭代器 for (int i=2;i<=n;i++){ int k,p;//在k同学旁边 p左边还是右边 0左边 1右边 scanf("%d%d",&k,&p); if (p == 0){//左边 pos[i] = stus.insert(pos[k],i);//在post[k]位置前插入i }else{//右边 list<int>::iterator it = pos[k]; ++it;//指向下一个元素 pos[i] = stus.insert(it,i);//插入post[k]后面一个位置 } } int m = 0; scanf("%d",&m);//移除m个人 for (int i=0;i<m;i++){ int x; scanf("%d",&x); if (!vis[x]){//没有移除过,则可以移除 保证只移除一次 stus.erase(pos[x]);//移除 vis[x] = true; } } for (list<int>::iterator i = stus.begin(); i != stus.end();i++){ printf("%d ",*i);//输出保留对应值 } return 0; }
循环链表
https://blog.csdn.net/kexuanxiu1163/article/details/105803458
将单链表中尾结点的指针由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表成为单循环链表,简称循环链表
https://www.luogu.com.cn/problem/P1996
//循环链表实现。流程:数到这个人就把这个人从链表元素中删除并输出编号 #include<bits/stdc++.h> using namespace std; struct node{ int data; node *next; }; int n,m; node *head,*p,*r; int main(){ scanf("%d %d",&n,&m); if(m==0)m=n;//m为0 数到0就出等同与数到n head=new node;//申请空间 head->data=1;//头节点数据置为1 head->next=NULL;//头节点下一个为空 r=head;//尾指针现在是头 头尾在一起 for(int i=2;i<=n;i++){ p=new node; p->data=i; p->next=NULL; r->next=p;//把申请的新节点连到前面的链表上 r=p;//尾指针后移一个 } r->next=head;//尾指针指向头 r=head;//循环链表建立完成 for(int i=1;i<=n;i++){ for(int j=1;j<=m-2;j++)r=r->next;//循环到m的前两个人 cout<<r->next->data<<" ";//输出这第m个人的数据 r->next=r->next->next;//跳过这个节点 r=r->next;//新的一轮从上次的最后一个的下一个开始 } return 0; }
作者:newcode 更多资源请关注纽扣编程微信公众号
从事机器人比赛、机器人等级考试、少儿scratch编程、信息学奥赛等研究学习