一维数组建立单链表
1.头插法建立单链表
y总写的模板
//head储存表头,e[]存储节点值,ne【】储存节点next指针,idex表示当前用到的节点
int head, idex ,e[],ne[],
void init()
{
head=-1;
idex=0;
}
//头插
//感觉跟数组没什么两样,但是这个可以作为逆序储存
void insert(int a)
{
e[idex]=a;
ne[idex]=head;
head=idex++;
}
2.双向链表
y总的模板,在竞赛中用静态的能加快编码速度
// e[]表示节点的值,l[]表示节点的左指针,r[]表示节点的右指针,idx表示当前用到了哪个节点
int e[N], l[N], r[N], idx;
// 初始化
void init()
{
//0是左端点,1是右端点
r[0] = 1, l[1] = 0;
idx = 2;
}
// 在节点a的右边插入一个数x
void insert(int a, int x)
{
e[idx] = x;
l[idx] = a, r[idx] = r[a];
l[r[a]] = idx, r[a] = idx ++ ;
}
// 删除节点a
void remove(int a)
{
l[r[a]] = l[a];
r[l[a]] = r[a];
}
作者:yxc
链接:https://www.acwing.com/blog/content/404/
来源:AcWing
约瑟夫问题
题目描述
n n n 个人围成一圈,从第一个人开始报数,数到 m m m 的人出列,再由下一个人重新从 1 1 1 开始报数,数到 m m m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。
输入格式
输入两个整数 n , m n,m n,m。
输出格式
输出一行 n n n 个整数,按顺序输出每个出圈人的编号。
样例 #1
样例输入 #1
10 3
样例输出 #1
3 6 9 2 7 1 8 5 10 4
提示
1 ≤ m , n ≤ 100 1 \le m, n \le 100 1≤m,n≤100
由题目分析最先想到的肯定是循环链表的建立与删除,主要能实现循环和删除
循环利用数组或者链表实现,删除利用双指针。
对于链表的实现用此题可以有多种解法,结合多个知识点
首先是最简单最方便的实现方法
题解
用一维数组实现单向静态链表
#include <iostream>
using namespace std;
int node[150];
int main(){
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n-1;i++)
{
node[i]=i+1; //很巧妙
}
node[n]=1;//结尾等于开头,构成循环
//以下是循环的思想跟后面解法的逻辑流程一样,
int prev=1,now=1; //从第一个开始
while((n--)>1){
for(int i=1;i<m;i++)
{
prev=now;now=node[now];//这一步理解很重要,保留前面节点,删除当前节点
}
printf("%d ",now);
node[prev]=node[now];
now=node[prev];
}
printf("%d",now);
return 0;
}
动态单向链表实现
是“教科书式”的标准做法
#include "bits/stdc++.h"
struct node{
int data;
node *next;
};//定义链表的结构体
int main()
{
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;
now->next=p;
now=p; //尾指针后移一个
}
now->next=head;//循环链表的建立
//以上是建立链表,从头节点一步步建立起链表
now=head,prev=head;//从第一个数开始
while((n--)>1){
for(int i=1;i<m;i++)
{
prev=now;
now=now->next;
}
printf("%d ",now->data);
prev->next=now->next;
delete now;
now=prev->next;
}
printf("%d",now->data);
delete now;
return 0;
}
用结构体数组实现单向静态链表
#include "stdio.h"
const int N=105;
struct node{
int id,nextid;
int data;//如果有必要定义一个有意义的数据
}node[N];//大数组定义在全局
int main()
{
int n,m;
scanf("%d %d",&n,&m);
node[0].nextid=1;
for(int i=1;i<=n;i++)
{
node[i].id=i;node[i].nextid=i+1;
}
node[n].nextid=1;
int now=1,prev=1;//双指针
while((n--)>1)
{
for(int i=1;i<m;i++)
{
prev=now;now=node[now].nextid;
}
printf("%d ",node[now].id);
node[prev].nextid=node[now].nextid;
now=node[prev].nextid;
}
printf("%d",node[now].nextid);
return 0;
}