c++链表经典题目--为学生排队

什么是链表?
A-B
A-B-C
A-C-B-D
把不同的元素用一定的办法连接起来的东西
这个连接的线我们一般用指针来做,即将前一个或下一个元素的地址放入目前元素的结构体中,来实现不同结构体(元素)之间产生联系
这种联系是可以改变的
A-C
我们把A,C连接后,如果要把B连在他们中间(第三者),我们就需要先A-B
再B-C,最后形成A-B-C(在下面的代码中有展示)

题目来自洛谷
点击查看题目

#include <bits/stdc++.h>
using namespace std;
struct _people
{
    struct _people *leftp=NULL;//前面的学生(结构体)的地址
    int num;//这个学生的号码
    struct _people *rightp=NULL;//后面的学生(结构体)的地址
} people[100005];
int main()
{
    int n;
    cin >> n;
    people[1].num=1;
    struct _people *head=&people[1];//设置链表的头,head
    for(int i=2; i<=n; i++)
    {
        people[i].num=i;//插入i学生的号码
        int x,vis;//x是follow哪一个学生,vis是与这个x学生的位置关系
        cin >> x >> vis;
        if(vis)//i在x的右边
        {
            if(people[x].rightp==NULL)//右边没有人,直接插入
            {
                people[x].rightp=&people[i];
                people[i].leftp=&people[x];
            }
            else//右边有人,这里就是在链表中间插入其他元素
            {
                people[x].rightp->leftp=&people[i];
                //先将x之前右边同学结构体中的left改为我们的i同学
                people[i].rightp=people[x].rightp;
                //和上一步对应,将i的右边改成x的原右边同学
                people[i].leftp=&people[x];
                //i的左边改成x同学
                people[x].rightp=&people[i];
                //与上一步对应,将x的右边改为i同学
            }
        }
        else//i在x的左边,以下步骤同理
        {
            if(people[x].leftp==NULL)
            //x的左边没有元素,说明它就是head,需要将head改成i
            {
                head=&people[i];
                people[i].rightp=&people[x];
                people[x].leftp=&people[i];
            }
            else
            {
                people[x].leftp->rightp=&people[i];
                people[i].leftp=people[x].leftp;
                people[i].rightp=&people[x];
                people[x].leftp=&people[i];
            }
        }
    }
    int m;
    cin >> m;
    for(int i=1; i<=m; i++)//将m个标为0
    {
        int x;
        cin >> x;
        people[x].num=0;
    }
    int flag=0;
    for(int i=1; i<=n; i++)
    {
        if(head->num)//如果是真才输出
        {
            if(!flag)
            {
                cout << head->num ;
                flag=1;
            }
            else
                cout << " " << head->num;
        }
        head=(head->rightp);//将haed改成指向目前head的left指向的学生(结构体)
    }
    cout << endl ;
    return 0;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值