首页 > 其他分享 >链表

链表

时间:2024-04-28 12:01:44浏览次数:22  
标签:node int next 链表 now define

P1996 约瑟夫问题

  1. 动态链表
    临时分配链表节点,使用完毕后释放链表节点。
    优点:能及时释放空间,不使用多余内存
    缺点:需要管理空间,容易出错。
#include <bits/stdc++.h>

#define int long long
#define rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define fep(i, a, b) for(int i = (a); i >= (b); --i)
#define _for(i, a, b) for(int i=(a); i<(b); ++i)
#define pii pair<int, int>
#define pdd pair<double,double>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define vi vector<int>

using namespace std;

struct node{
    int data;
    node *next;
};

void solve() {
    int n,m; scanf("%d %d", &n, &m);
    node *head, *p, *now, *prev;
    head = new node; head->data = 1; head->next = NULL;
    now = head; //当前指针是头
    for(int i=2;i<=n;i++){
        p = new node; p->data = i; p->next = NULL; //p是新节点
        now->next = p; //把申请的新节点镰刀前面的链表上
        now = p; //把问指针后移一个
    }
    now->next = head;   //尾指针指向头:循环链表建立完成
    now = head, prev = head;    //从第一个开始数
    while((n--)>1){
        for(int i=1;i<m;i++){   //数到m,停下
            prev = now; //记录上一个位置,用于下面跳过第m个节点
            now = now->next;
        }
        printf("%d ", now->data); //输出第m个结点,带空格
        prev->next = now->next; //跳过这个节点
        delete now; //释放节点
        now = prev->next;   //新的一轮
    }
    printf("%d", now->data);    //打印最后一个节点,后面不带空格
    delete now; //释放最后一个节点
    return ;
}

signed main() {
//    ios::sync_with_stdio(false);
//    cin.tie(0);
//    cout.tie(0);
//	freopen("C:\\Users\\24283\\CLionProjects\\untitled2\\1.in", "r", stdin);
//    int _;
//    cin >> _;
//    while (_--)
        solve();
    return 0;
}
  1. 静态链表
    预先分配一段连续空间存储链表。
    有两种实现方法:
  2. 定义结构体数组和动态链表的结构差不多
  3. 使用一维数组,直接在数组上进行链表操作
#include <bits/stdc++.h>

using namespace std;

const int N = 105;
struct node{ //单向链表
    int id, nextid; //单向指针
    int data;
}nodes[N];

int main() {
    int n,m;    scanf("%d%d",&n,&m);
    nodes[0].nextid = 1;
    for(int i=1;i<=n;i++){nodes[i].id=i;nodes[i].nextid=i+1;}
    nodes[n].nextid = 1; //循环链表:尾指向头
    int now = 1, prev = 1; //从第一个节点开始
    while((n--)>1){
        for(int i=1;i<m;i++){prev = now; now = nodes[now].nextid;}  //数到m停下
        printf("%d ", nodes[now].id);   //带空格打印
        nodes[prev].nextid = nodes[now].nextid; //跳过now节点,即删除now
        now = nodes[prev].nextid;   //新的now
    }
    printf("%d",nodes[now].nextid); //打印最后一个节点,后面不带空格
    return 0;
}

双向循环链表

#include <bits/stdc++.h>

using namespace std;

const int N = 105;
struct node{ //双向链表
    int id; //节点编号
    int data;
    int preid, nextid; //前一个节点,后一个节点
}nodes[N];

int main() {
    int n, m;   scanf("%d%d",&n,&m);
    nodes[0].nextid = 1;
    for(int i = 1;i<=n;i++){    //建立链表
        nodes[i].id = i;
        nodes[i].preid = i-1;
        nodes[i].nextid = i+1;
    }
    nodes[n].nextid = 1;    //循环链表:尾指头
    nodes[1].preid = n;     //循环链表:头指尾
    int now = 1;
    while((n--)>1){
        for(int i = 1;i<m;i++)  now = nodes[now].nextid;
        printf("%d ",nodes[now].id);
        int prev = nodes[now].preid, next = nodes[now].nextid;
        nodes[prev].nextid = nodes[now].nextid;
        nodes[next].preid = nodes[now].preid;
        now = next;
    }
    printf("%d", nodes[now].nextid);
    return 0;
}
  1. STL list
    算法竞赛或工程项目中常常使用C++ STL list。list是双向链表,由标准模板库(STL)管理,通过指针访问节点数据,高效率地删除和插入。
#include <bits/stdc++.h>

using namespace std;

const int N = 105;

int main() {
    int n, m;   cin>>n>>m;
    list<int>node;
    for(int i = 1;i<=n;++i) node.push_back(i);  //建立链表
    list<int>::iterator it = node.begin();
    while(node.size()>1){
        for(int i=1;i<m;++i){
            it++;
            if(it == node.end())    it=node.begin();
        }
        cout<<*it<<" ";
        list<int>::iterator  next = ++it;
        if(next==node.end())    next=node.begin();
        node.erase(--it);
        it = next;
    }
    cout<<*it;
    return 0;
}

标签:node,int,next,链表,now,define
From: https://www.cnblogs.com/cxy8/p/18163341

相关文章

  • 双向循环链表接口设计
    /***************************************************filename:DoubleDoubleCirLkList.c*author:[email protected]*date:2024/04/25*brief:通过构建双向循环链表学习顺序存储*note:None**CopyRight(c)2024momolyl@126......
  • 链表逆序
    编写一个函数,实现单链表逆序,,函数原型如下:*voidreverse_list(single_listhead)程序代码如下:voidreverse_list(single_list*head){single_list*p=head->next;//将链表除头节点的节点保存head->next=NULL;//将链表断开single_list*tmp=NULL;while(......
  • 单向循环链表接口设计
    目录单向循环链表接口设计创建新的头结点创建新节点并初始化该节点工具函数遍历链表查找尾结点查找尾结点前置驱动找到指定结点查找指定节点前置驱动创建每一个新节点并插入到头部新建结点并插入到尾部新建结点并插入到指定节点之后删除头部结点删除尾部结点删除指定结点调试函数......
  • 双向循环链表的头插法的实现
    include<stdio.h>include<stdlib.h>typedefstructslik{intdata;structslik*next;structslik*prev;}sli;voidcreatesli(sli**head,inta[],intsize){for(inti=0;i<size;i++){sli*s=(sli*)malloc(sizeof(sli));s->data=a[i];......
  • 单向循环链表的头插法实现
    ``#include<stdio.h>``````include<stdlib.h>typedefstructslik{intdata;structslik*next;}sli;voidcreatesli(sli**head,inta[],intsize){for(inti=0;i<size;i++){sli*s=(sli*)malloc(sizeof(sli));s->data=a[i];s->......
  • 单向循环链表的尾插法实现
    `#include<stdio.h>include<stdlib.h>typedefstructslik{intdata;structslik*next;}sli;voidcreatesli(sli**head,inta[],intsize){for(inti=0;i<size;i++){sli*s=(sli*)malloc(sizeof(sli));s->data=a[i];s->next=NU......
  • 单向链表队列程序接口设计
    目录目录单向链表构建队列的接口函数库函数的调用指的是链表队列中的元素的数据类型,用户可以根据需要进行修改构造记录链表队列LinkQueueNode各项参数(链表队列结点的指针指向的下一个结点地址+链表队列的结点数据)的结构体构造记录链表队列LinkQueue各项参数(链表队列的队首地......
  • 数据结构_链表_双向循环链表的初始化、插入、删除、修改、查询打印(基于C语言实现)
    版本:2024年4月26日V1.0发布于博客园/***@filename:DoubleLinkedList.c*@brief:实现双向循环链表的相关功能*@author:[email protected]*@date:2024/04/26*@version:1.0*@note:*CopyRight(c)2023-2024RISE_AND......
  • 以链表为基础实现链式队列
    以链表为基础实现链式队列如果打算以链表作为基础来实现队列的操作,可以避免内存浪费以及避免内存成片移动,只需要确定队头和队尾即可,一般把链表头部作为队头,可以实现头删,把链表尾部作为队尾,可以实现尾插。#include<stdio.h>#include<stdbool.h>#include<stdlib.h>//对输入......
  • 双向循环链表
    双向循链表双向循环链表我是在双向循环链表上进行升级,就是双向循环链表首结点和尾结点相链接,首结点的prev链接尾结点本身,尾结点的next链接首结点本身,在对头部或者尾部操作的时候与双向链表有区别,具体代码写在下面。希望看完代码的你发现错误,请评论批评指正,非常感谢。目录双......