约瑟夫环问题循环单链表(约瑟夫问题数据结构循环链表)

http://www.itjxue.com  2023-01-27 19:48  来源:未知  点击次数: 

java循环单链表实现约瑟夫环

看了你的代码,不是很明白,给你提几个建议吧:

1、不需要tail节点

2、remove方法应该对删除节点前面的节点操作,而不是使用数字找

给你我修改的LinkList类,你参考一下:

public?class?LinkList?{

private?Node?head;

int?curlen?=?0;

//?创建链表

public?void?createlist(int?code)?throws?Exception?{

insert(curlen,?code);

}

public?void?insert(int?i,?int?code)?throws?Exception?{

Node?s?=?new?Node(code);

if?(i?==?0)?{

s.setNext(head);

head?=?s;

}

Node?p?=?head;

int?j?=?0;

while?(p?!=?null??j??i?-?1)?{

p?=?p.getNext();

j++;

}

if?(j??i?||?p?==?null)?{

throw?new?Exception("插入位置不合理");

}

s.setNext(p.getNext());

p.setNext(s);

// tail?=?s;

// tail.setNext(head);

curlen?=?curlen?+?1;

}

public?void?remove(int?i)?throws?Exception?{

Node?p?=?head,?q?=?null;

int?j?=?0;

i?=?i?-?1;

while?(j??i)?{

q?=?p;

p?=?p.getNext();

j++;

}

if?(j??i?||?p?==?null)

throw?new?Exception("删除位置不合法");

if?(q?==?null)?{

// tail.setNext(p.getNext());

head?=?head.getNext();

}?else

q.setNext(p.getNext());

curlen?=?curlen?-?1;

}

/**

?*?按照节点删除

?*?@param?i

?*?@throws?Exception

?*/

public?void?remove(Node?p)?throws?Exception?{

if(p.getNext()==p){

p=null;

head=null;

}

else{

Node?q?=?p.getNext();

p.setNext(q.getNext());

}

curlen?=?curlen?-?1;

}

public?void?out(int?m)?throws?Exception?{

Node?p?=?head;

if(m==1){

System.out.print("按照顺序出列");

return;

}

int?count?=?1;

int?n=m-1;

while?(curlen??0)?{

if?(count?==?n)?{

System.out.print(p.getNext().getData()?+?"??");

remove(p);

count?=?1;

}?else?{

count++;

}

p?=?p.getNext();

}

}

public?void?display()?{

Node?node?=?head;

for?(int?i?=?0;?i??2?*?curlen;?i++)?{

System.out.print(node.getData()?+?"?");

node?=?node.getNext();

}

System.out.println();

}

}

c语言链表写约瑟夫环问题

C语言的约瑟夫环问题,利用单循环链表,代码如下:

#includestdio.h??//利用单循环链表!!!!!

#includestdlib.h

#includemalloc.h

typedef?int?ElemType;

typedef?struct?SingleNode

{

?ElemType?data;

?struct?SingleNode?*next;

}SLL,*LinkList;

int?main()

{

?SLL?*head?,*use,*temp;

?int?i,n,m,k,a=0;

?printf("请输入总人数n:");?

?scanf("%d",n);

?????

?printf("从第m个人开始数起,请输入m:");?

?scanf("%d",m);

?????

?printf("数到第k个人,该人出列,请输入k:");?

?scanf("%d",k);

??

?head?=?use?=?(SLL?*)?malloc(sizeof(SLL));//建立链表,形成链表头

???head-data?=?1;

??

???for?(i?=?2;?i?=?n;?i++)//形成其余的n-1个

???{

????use-next?=?(SLL?*)?malloc(sizeof(SLL));

????use?=?use-next;

????use-data?=?i;//第i个置编号i

???}

???use-next?=?head;//末首相连,形成环

?printf("人员序号为:");??//输出人员的序号

?temp=head;

?for(i=0;in;i++)

?{

??printf("%d?",temp-data);

??temp=temp-next;

?}

?printf("\n");

??

?for(i=0;im-1;i++)//use指向第m-1个,为了从m位开始数

?{

??use=use-next;

?}

printf("人员出列顺序为:");

while?(n)?{

?for?(i?=?1;?i??k;?i++)//掠过k-1个

??use?=?use-next;

?temp?=?use-next;//temp指向第k个

?use-next?=?temp-next;//第k个从环中脱钩

?printf("%d?",?temp-data);

?free(temp);//释放第k个表元占用的空间

?n--;

}

printf("\n");

?return?0;

}

单链表实现代码如下:

#includestdio.h??//这是使用单链表做的约瑟夫环

#includestdlib.h

#includemalloc.h

typedef?int?ElemType;

typedef?struct?SingleNode

{

ElemType?data;

struct?SingleNode?*next;

}SLL,*LinkList;

void?ListInitialize(SLL?**head)???//初始化

{

if?((*head=(SLL?*)malloc(sizeof(SLL)))==NULL)

exit(1);

(*head)-next=NULL;

}

int?ListInsert(SLL?*head,int?i,ElemType?x)??//插入

{

SLL?*p,*q;

int?j;

p=head;

j=-1;

while(p-next!=NULLji-1)

{

p=p-next;

j++;

}

if(j!=i-1)

{

printf("the?i?is?wrong!");

return?0;

}

if((q=(SLL?*)malloc(sizeof(SLL)))==NULL)

exit(1);

q-data=x;

q-next=p-next;

p-next=q;

return?1;

}

int?ListGet(SLL?*head,int?i,ElemType?*x)???//取

{

SLL?*p;

int?j;

p=head;

j=-1;

while(p-next!=NULLji)

{

p=p-next;

j++;

}

????if(j!=i)

{

printf("ERROR!");

return?0;

}

??*x=p-data;

return?1;

}

void?yuesefu(SLL?*head,?ElemType?n,ElemType?m,ElemType?k)??//约瑟夫删除操作

{ElemType?x;

SLL?*p,*s;

????p=head;

int?i=0,j=0,b=0;

while(b!=m-1)??//将指针指到第m-1个元素

{

p=p-next;

b=b+1;

}

while(p-next!=NULL)??

{while(i!=k-1)

{i=i+1;

p=p-next;

if(p==NULL)??p=head-next;??//控制循环

}

??????

??if(p-next==NULL)??p-next=head-next;???//控制循环

s=p-next;??//删除第k个元素

???x=s-data;

????????if(s-next==NULL)??s-next=head-next;??//控制循环??

p-next=s-next;

printf("%d?",x);??//输出第k个元素

j=j+1;???//用以统计总共输出了多少个元素

free(s);

if(j==n)?break;

i=0;???//i清零

}

}

void?main()

{

SLL?*head;

int?x,i,n,m,k,a=0;

ListInitialize(head);?//调用初始化函数

printf("请输入总人数n:");?

scanf("%d",n);

????

printf("从第m个人开始数起,请输入m:");?

scanf("%d",m);

????

printf("数到第k个人,该人出列,请输入k:");?

scanf("%d",k);

for(i=0;in;i++)???//生成人员的序号

{???a=a+1;

ListInsert(head,i,a);

}

printf("人员序号为:");??//输出人员的序号

for(i=0;in;i++)

{

ListGet(head,i,x);

printf("%d?",x);

}

printf("\n");

printf("人员出列顺序为:");

????yuesefu(head,n,m,k);

printf("\n");

}

约瑟夫环(单循环链表)

m个人围成一个圈,指定一个数字n,从第一个人开始报数,每轮报到n的选手出局,由下一个人接着从头开始报,最后一个人是赢家。其中m1,n2。

用一个不带头节点的循环链表来处理,先构成一个有m个节点的单循环链表,然后由n节点开始计数,每计数到n时对应节点从链表中删除,然后再从删除节点的下一个节点又从1开始计数,直到最后一个节点从链表中删除算法结束。

1.创建一个空指针first,这个first暂时不动,只指向第一个加入进来的对象。

2.先创建第一个节点,并用first指向它,同时它的next是它自己,形成一个闭环。同时创建一个currentNode节点指向最后一个节点,为增加其它节点做准备。

3.加入其它节点时,首先将currentNode的next设置为新的节点node,然后把新节点的next指向回没有动的first节点形成闭环,最后将currentNode指向新的节点。

建立一个重要的指针helper,辅助弹出功能

first 当前计数的节点,helper则指向first的上一个节点

first和helper指针同时前移的时候,first数到对应的数字n,helper还是到它的前一个。弹出first后,first前移以为,helper的next指向first,就弹出了对应的那个节点

(责任编辑:IT教学网)

更多

推荐Painter教程文章