逻辑算法大赛辅导--单循环链表的倒置与显示、与约瑟夫问题

zengyiCSTC 2004-02-16 11:22:50
本系列主题主要为准备参赛的同学奠定坚实的算法与数据结构基础

单循环链表的倒置与显示、与约瑟夫问题

本内容使原来写过的一个单循环链表相关问题的实现:
生成一个带结点的单循环链表,并将它显示出来,再把它倒置。通过人机对话输入结点的数目,模和开始的元素,然后进行约瑟夫运算,求出输出序列。实现将一个链表转成一个顺序存储线性表。
关于一个单循环链表的实现:可以通过不断地加入结点来达到。而它的显示也是可以通过不断地找下一个结点来实现。
关于表的倒置:可以通过让每一个结点指向其前继来完成。
操作运算与目的
1、加入结点的操作 AddNode(完成一个单循环链表的建立),并在主函数中不断调用来建立链表。
2、显示完整链表的操作Display。
3、显示约瑟夫运算后的结果DisplayYsf。
4、把一个链表转换成一个顺序存储的链表Convert。
2、 物理存储结构:
定义
1.结点定义
struct Node //结点结构体
{
int data; //结点中的数据
Node * Next; //下一个结点的指针
};
2. 表定义
class LoopLink //一个表的类
{
Node * Header; //表的头指针
public:
LoopLink(){Header=NULL;} //表的初始化
void AddNode(int e); //加入结点
void Display(void); //显示
void Rev(void); //倒置
void DisplayYsf(int e,int m); //显示约瑟夫问题答案
};
3、算法、设计
a)加入结点(AddNode):
1、如果表中无结点,建立一个新的结点并让头指针指向它。
2、如果有结点,找到那个后继指向头结点的结点,建立一个新的结点, 其后继为头结点,前驱是刚刚找到的那个结点。
b)显示结点(Display):
1、用一个临时指针从头结点开始一个个结点地访问并显示数据。
2、如果找到了后继为头结点的结点就结束。
c)表的倒置(Rev):
1、用t,p,temp分指向开始的三个连续的结点。
2、把p的后继改成t,三个指针向后走一个结点,temp主要是存储p原来的后继。
3、当p指向的是头结点时,t指向的一定的表尾,存储这个地址。
4、当t回到了头结点,把表尾地址给头指针。倒置完成。
d)把一个链式表转换成一个顺序存储的表(Convert)
1、用一个临时指针从头结点开始一个个结点访地问并把数据一个个放到一个一维数组里去。
2、如果找到了后继为头结点的结点就结束
e)实现约瑟夫问题:(Convert)
1、找到元素与给定的值匹配的结点。
2、开始约瑟夫循环,直到最后一个自己指向自己的结点。
3、每一次循环找到一个相应的点,将其删除。
4、把最后一个结点删除。
运行测试结果
1、首先程序会问链表长
Now You must create a Link:
Please input the number of Link Node:
2、然后会让你依次输入每一个元素如Input the [0] number of Node:
3、程序会自动显示一次刚刚输入的表:如 1 2 3 4 5
4、接着,它会把表倒置并显示出来:如 5 4 3 2 1 并把它转换成顺序表显示一次。
5、然后,开始约瑟夫问题:先输入一个开始的元素,
Please input the data whose Node will be start point:
再输入模 Please input the mod number:
最后程序会自动显示出答案。

链表逆转
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
typedef struct node{
char data;
struct node *next;
}node;
node *head;

void creatlist()
{
node *p,*q,*r;
int a,b;
printf("please input some numbers/n");
scanf("%c",&b);
if(b!=Ɔ')
{
p=(node*)malloc(sizeof(node));
p->data=b;
head->next=p;
r=p;
a=getchar();
while(a!=Ɔ')
{
p=(node*)malloc(sizeof(node));
p->data=a;
r->next=p;
r=r->next;
a=getchar();
}
r->next=head;
}
else printf("NULL");
getch();
}
void invert()
{
node *p,*q,*r;
p=head->next;q=NULL;
while(p!=NULL)
{
r=q;
q=p;
p=p->next;
q->next=r;
}
head->next=q;
p=head;
p=p->next;
while(p!=head)
{printf("%c",p->data);
p=p->next;
}
}
void main()
{
clrscr();
creatlist();
printf("start inverting/n");
invert();
printf("stop inverting/n");
getch();
}

约瑟夫圈:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<dos.h>
typedef struct Data
{int no;
int password;
};
typedef struct list
{struct Data data;
struct list *next;
};
int num,m,i,j,l;
list *head,*tail,*p,*q,*pt,*pr,*pir;
void Input()
{
printf("Enter the total num =");
scanf("%d",&num);
printf("\nEnter the limt m=");
scanf("%d",&m);
if(num==0||m==0)
{ printf("Sorry ,there is no record in the queue!");
exit(0);
}

p=head=tail= (list *)malloc(sizeof(list));
p->data.no=1;
p->data.password=random(50)+1;
tail->next=head;
printf("\nNo-------------password");
printf("\n1\t\t%d",p->data.password);

for(i=2;i<=num;i++)
{
p=(list *)malloc(sizeof(list));
p->data.no=i;
p->data.password=random(50)+2;
printf("\n%d\t\t",i);
printf("%d",p->data.password);
delay(200);
p->next=head;
tail->next=p;
tail=p;
}
printf("\n\n");
}

void Process()
{ pr=tail->next;
j=1;
gotoxy(37,5);
printf("Out order NO------------its password\n");
while(num!=0)
{ l++;
while(j!=m-1)
{j++;pr=pr->next;}
pt=pr->next;
pr->next=pt->next;
pr=pr->next;
gotoxy(36,5+l);
printf("\t%d\t\t\t%d\n",pt->data.no,pt->data.password);
delay(100);
num--;
j=1;
m=pt->data.password;
if(m>=num) m=m-(m/num)*num;
free(pt);
}
}
void main()
{
clrscr();
Input();
Process();
}

约瑟夫(顺序表):
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include<dos.h>
void main()
{
struct Queue{
int *b;
int i;
};
int i,j,n,m,k;
struct Queue Q;
printf("please input n,m,k\n");
scanf("%d,%d,%d",&n,&m,&k);
Q.b=(int *)malloc(n*sizeof(int));
Q.i=0;
for(i=0;i<=n-1;i++) printf("%d ",Q.b[Q.i+i]=i+1/n);
putchar('\n');
Q.i=k-2;
for (i=1;i<=n-1;i++)
{
for (j=1;j<=m;j++)
{
while (!Q.b[Q.i+1])
{
Q.i++;
if (Q.i==n) Q.i=0;
if (Q.i==n-1 && !Q.b[n-1] && !Q.b[0]) Q.i=0;
}
Q.i++;
if (Q.i==n) Q.i=0;
}
printf("%d ",Q.b[Q.i]/n);
Q.b[Q.i]=0;
}
while (!Q.b[Q.i])
{
Q.i++;
if(Q.i==n) Q.i=0;
}
clrscr();
printf("%d ",Q.b[Q.i]);
delay(500);
}

...全文
208 点赞 收藏 8
写回复
8 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
laughly 2004-04-04
什么是约瑟夫问题 ?
回复
xianliti 2004-03-22
while(p!=NULL)
{
r=q;
q=p;
p=p->next;
q->next=r;
}
是用三个指针遍历整个链表来实现链表的倒置.

之后的代码就是打印出倒置后 的结果了
回复
icefishchwd 2004-03-22
我觉得应该将q=NULL;改为q=head;
回复
icefishchwd 2004-03-21
请教一下:
p=head->next;q=NULL;
while(p!=NULL)
{
r=q;
q=p;
p=p->next;
q->next=r;
}
head->next=q;
p=head;
p=p->next;
while(p!=head)
{printf("%c",p->data);
p=p->next;
}
这段是什么意思啊?
回复
JIH488 2004-03-21
此问题是数据结构题之一
请看书
回复
xianliti 2004-03-20
N个人围成一圈,从第M个人开始循环报数(从1开始报),每报到S的这个人出列,
(出列的人不参加下一轮的报数)
然后接着从下一个人开始报数,同样报到S的人出列,直到全部人出列。

回复
www82621677 2004-03-20
总的来说还可以把。你是自己编写的吗
有个问题啊
] e)实现约瑟夫问题:(Convert)
1、找到元素与给定的值匹配的结点。
2、开始约瑟夫循环,直到最后一个自己指向自己的结点。
3、每一次循环找到一个相应的点,将其删除。
4、把最后一个结点删除。


想问一下。实现约瑟夫问题 具体的步骤啊
回复
caocao123 2004-03-16
shit~~~~
回复
相关推荐
发帖
其他
创建于2009-10-09

222

社区成员

其他产品/厂家
申请成为版主
帖子事件
创建了帖子
2004-02-16 11:22
社区公告
暂无公告