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;
}

 

posted @ 2021-06-27 10:51  new-code  阅读(133)  评论(0编辑  收藏  举报