您的位置: 网站首页 > 程序开发 > 数据结构 > 第2章 线性表 > 【2.5 上 机 实 验】

2.5 上 机 实 验

 

2.5 

2.5.1  实验内容

1)将带头节点的单链表的所有节点逆置。

2)利用顺序表求解约瑟夫问题。

3)计算一个循环链表中节点的个数。

2.5.2  实验指导

1)将带头节点的单链表的所有节点逆置。

上机实现算法:将一个节点数据域依次是a1a2,……,ann3)的带头节点的单链表的所有节点逆置,即第一个节点的数据域变为an,最后一个节点的数据域为a1

采用头插法建立一个新表,算法如下:

void reverse(SNode *h)

{

   SNode *p,*q;

   p=h->next;

   h->next=NULL;                 /*建立一个带头节点的空表*/

   while (p!=NULL)

   {

      q=p->next;

      p->next=h->next;            /**p节点插入到头节点之后*/

      h->next=p;

      p=q;

   }

}

2)利用顺序表求解约瑟夫问题。

求解约瑟夫问题:n只猴子要选大王,选举方法是,所有猴子按12,……,n编号围坐一圈,从第1号开始按12,……,m报数,凡报到m号的退出圈外,如此循环报数,直到圈内剩下一只猴子时,这只猴子就是大王。编写一个程序求猴子出列的次序,其中nm由键盘输入。

解:这里采用顺序表进行存储,使用一个数组mon,最多可存放MaxSize个元素,初始时mon[i]中存放猴子的编号i+1(猴子的编号为1n),将出列猴子个数计数器count置为0d置为0,从mon[0](其编号为1)开始循环报数,每报一次,d值加1,凡报到m(条件d==m成立)时便输出mon[i]的值,同时将mon[i]的值改为0(表示该猴子已出列)。该过程一直进行到n只猴子全部退出圈外为止(条件count==n成立),最后退出的便是大王。实现本题功能的程序如下:

void jose(int n,int m)

{

    int mon[MaxSize];                    /*存放n个猴子的编号*/

    int i,d,count;

    for (i=0;i<n;i++)                    /*设置猴子的编号*/

        mon[i]=i+1;

    printf("出队前:");                   /*输出出列前的编号*/

    for (i=0;i<n;i++)

        printf("%d ",mon[i]);

    printf("\n");

    printf("出队后:");

    count=0;                             /*记录退出圈外的猴子个数*/

    i=-1;                                /*0号位置的猴子开始计数*/

    while (count<n)

    {  

d=0;

        while (d<m)                    /*累计m个猴子*/

        {  

i=(i+1)%n;                 /*循环选取*/

            if (mon[i]!=0)

                d++;

        }

        printf("%d ",mon[i]);           /*猴子出列*/

        mon[i]=0;

        count++;                        /*出列数加1*/

    }

    printf("\n");

}

执行本程序,在输入猴子个数分别是104时输出结果如下。

出队前:1 2 3 4 5 6 7 8 9 10

出队后:4 8 2 7 3 10 9 1 6 5

3)算法只需扫描一次链表,同时设立一个计数变量用来计数即可。

int Count ( )

{

   int i;

   LinkList *p;

   p=head;

   i=0;

   while ( p->next!=head )

   {

      p=p->next;

      i++;

   }

      return ( i );

}