链表解决约瑟夫环问题

约瑟夫环问题

(1)链表解决约瑟夫环问题

算法描述:

编号为1,2,...,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。现在给定一个随机数m>0,从编号为1的人开始,按顺时针方向1开始顺序报数,报到m时停止。报m的人出圈,同时留下他的密码作为新的m值,从他在顺时针方向上的下一个人开始,重新从1开始报数,如此下去,直至所有的人全部出列为止。

源程序:

#include<stdio.h>

#include<malloc.h>

#define MAX 30

typedef struct node{

       int num;

       int sec;

       struct node *next;

}node,*pnode;

void main()

{

       int m,n,i,del;

       pnode p,p1,head;

       printf("enter m:\n");

       scanf("%d",&m);

       printf("how many people?\n");

       scanf("%d",&n);

    if(n>MAX) {printf("enter error!please enter n again:\n");}

       printf("enter %d people`s secrets:\n",n);

    p=(pnode)malloc(sizeof(node));

    scanf("%d",&p->sec);

       p->num=1;

       head=p;

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

       {

              p1=(pnode)malloc(sizeof(node));

              scanf("%d",&p1->sec);

              p1->num=i;

              p->next=p1;

              p=p1;

       }

       p1->next=head;

       del=0;

       while(del!=n)

       {

              for(i=1;i<m;i++)

              {

                  p1=head;

                  head=head->next;

              }

              printf("%d    ",head->num);

           m=head->sec;

           p1->next=head->next;

              del++;

              head=head->next;

       }

       printf("\n");

}

测试数据:

 

(2)用顺序存储结构解决约瑟夫环问题

算法描述:

在int a[n] 中,n表示编号,a[n]的值表示密码,当a[i]被删除时,令a[i]=0;用i计数.

源程序:

#include<stdio.h>

#define MAX 30

void main()

{

       int m,n,i,del,b;

       int a[MAX];

       printf("enter n:\n");

       scanf("%d",&n);

       if(n>MAX) {printf("enter error! enter n again:\n");scanf("%d",&n);}

       printf("enter m:\n");

       scanf("%d",&m);

       printf("enter %d people`s secrets:\n",n);

       for(i=1;i<=n;i++) scanf("%d",&a[i]);

       del=0;

       b=0;

       while(del!=n)

       {

              for(i=1;i<=m;i++)

              {

                     b++;

                     if(b==n+1) b=1;

                     if(a[b]==0) i--;

              }

              m=a[b];

              a[b]=0;

              del++;

              printf("%d   ",b);

       }

       printf("\n");

}

测试数据:

 

 

 

 

 

:文学小助手

算法描述:

利用串定义的一些函数,strlen()和strindex(),查找文本文档中的相应数据。

源程序:

#include<stdio.h>

#include<malloc.h>

#include<stdlib.h>

#define H 1000

#define N 100

typedef struct node

{

       int line;

       int time;

    struct node *next;

}node,*pnode;

typedef struct

{

       char *ch;

       int len;

}string;

int strlen(string *a1)

{

       int i;

       char *p;

       i=0;

       p=(*a1).ch;

       while(*p!='\0')

       {

              i++;

              p++;

       }

       return i;

}

int strindex(string *a1,string *a2)

{

       int i,j,tag;

       char *p1,*p2;

       i=0;

       j=0;

       tag=0;

       p1=(*a1).ch;

       p2=(*a2).ch;

       while(*(p1+i)!='\0'&&*(p2+j)!='\0')

       {

              if(*(p1+i)==*(p2+j)&&j==0)

              {

            tag=i;

                     i++;

                     j++;

                     continue;

              }

              if(*(p1+i)==*(p2+j)&&j!=0)

              {

                     i++;

                     j++;

                     continue;

              }

              if(*(p1+i)!=*(p2+j))

              {

                     j=0;

                     i=tag+1;

                     tag++;

              }

       }

       if(*(p2+j)=='\0') return (tag+1);

       if(*(p1+i)=='\0') return -1;

}

int search(string *a1,string *a2)

{

    string s,*w;

       char *p1,*p;

       int t,len2,x,z,n;

       n=0;

       z=1;

    len2=strlen(a2);

       p1=(*a1).ch;

       w=a1;

       x=0;

       t=0;

    while(t!=-1)

       {

              t=strindex(w,a2);

              if(t!=-1)

              {

                     n++;

                  if(z==1) x=x+t-1;

                  else x=x+len2+t-1;

                  p=p1+x+len2;

            s.ch=p;

               w=&s;

                  z++;

              }

              else break;

}

       return n;

}

void main()

{

       char s[50];

       FILE *fp;

       pnode p1,p2,head;

       int i,n,t;

    string s1,s2;

       s1.ch=(char *)malloc(sizeof(char)*H);

    s2.ch=(char *)malloc(sizeof(char)*N);

       printf("enter the file's way:\n");

       gets(s);

       printf("enter the key word:\n");

       gets(s2.ch);

       i=1;

       n=0;

    head=p1=(pnode)malloc(sizeof(node));

    s1.len=strlen(&s1);

       s2.len=strlen(&s2);

       if((fp=fopen(s,"r"))==NULL)

       {

              printf("cannot open the file!\n");

              exit(0);

       }

    while(!feof(fp))

       {

        fgets(s1.ch,H,fp);

        t=search(&s1,&s2);

              if(t!=0)

              {

                     (*p1).line =i;

                     (*p1).time=t;

                     p2=p1;

                     p1=(pnode)malloc(sizeof(node));

                     (*p2).next=p1;

              }

              n=n+t;

              i++;

       }

       (*p2).next=NULL;

    printf("the total time is:%d\n",n);

       p1=head;

       while(p1!=NULL)

       {

              printf("line %d   time %d\n",(*p1).line,(*p1).time);

              p1=p1->next;

       }

}

 

测试数据:

 

 

 

 

 

 

 

哈夫曼编/译码器

算法描述:

利用哈夫曼树的知识编程。

源程序:

#include<stdio.h>

#include<stdlib.h>

#include<malloc.h>

#include<string.h>

#define N 8

#define H 1000

typedef struct node

{

       int weight;

    struct node *parent;

       struct node *lchild;

       struct node *rchild;

       char dj;

}node,*pnode;

//............................................................................................................

void search(pnode p,int m,int *a,int *v)//查找根结点中权值最小的两项

{

       int t1,t2,j,tag;

       t1=t2=-1;

       for(j=0;j<=m;j++)

       {

              tag=t1;

              if(t1==-1&&(p+j)->parent==0) t1=j;

              if(tag!=-1&&t2==-1&&(p+j)->parent==0) t2=j;

              if(t1!=-1&&t2!=-1&&(p+t1)->weight>(p+t2)->weight)

              {

                     tag=t1;

                     t1=t2;

                     t2=tag;

              }

              if(t1!=-1&&t2!=-1) break;

       }

       tag=t1;

             

       for(j=0;j<=m;j++)

       {

              if(j!=tag&&(p+j)->weight<(p+t2)->weight&&(p+j)->parent==0)

              {

                     if((p+j)->weight>(p+t1)->weight) t2=j;

                     else

                     {

                            t2=t1;

                            t1=j;

                     }

              }

       }

       *a=t1;

       *v=t2;

}

//....................................................................................................

void main()

{

    FILE *fp;

       pnode HT,p,f,flast,child;

       char ch;

       char a[N+1],wj[50],mi[500];

       char code[H];

       char da[N][N];

       char *cd;

       char **HC;

       int n,j,m,t1,t2,tag,h;

    int w[N+1];

       int *v;

    code[0]='\0';//注意code[]要先这样初始化呀!!!!!!!!!!!!!!!!!!!!!!!!!!!!

       HC=(char **)malloc(sizeof(char *)*N);

       cd=(char *)malloc(sizeof(char)*N);

       *(cd+N-1)='\0';

       v=w+1;

       m=2*N-1;

       n=N;

       tag=N-1;

       printf("enter the string which has %d letters:\n",n);//a[]存放需要发送的字母,w[]存放相应字母的权值,其中w[0]单元未用

       gets(a);

       printf("enter the %d weight:\n",n);

       for(j=1;j<=N;j++,v++) scanf("%d",v);

       getchar();

    p=HT=(pnode)malloc(sizeof(node)*m);

       for(j=1;j<=N;j++)//初始化2N-1个结点,使前N个结点的weight值为w[]中的相应权值,所有结点其余项全为0

       {

              p->weight=w[j];

              p->parent=0;

              p->lchild=0;

              p->rchild=0;

              p++;

       }

       p=HT;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!找了那么久,错误竟是忘了给p重新赋HT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

       for(j=N;j<=m-1;j++)

       {

              (p+j)->weight=0;

              (p+j)->parent=0;

              (p+j)->lchild=0;

              (p+j)->rchild=0;

       }

       for(j=1;j<=N-1;j++)//构造哈夫曼树

       {

              search(HT,tag,&t1,&t2);

              if((HT+t1)->weight==(HT+t2)->weight)

              {

                     (HT+t1)->dj='0';

                     (HT+t2)->dj='1';

              }

              (HT+tag+1)->lchild=HT+t1;

              (HT+tag+1)->rchild=HT+t2;

        (HT+tag+1)->weight=(HT+t1)->weight+(HT+t2)->weight;

              (HT+t1)->parent=(HT+t2)->parent=HT+tag+1;

              tag++;

       }

    for(j=0;j<=N-1;j++)//根据哈夫曼树,从叶子结点逆向到根结点,得到各个字符的前缀编码

       {

              h=N-2;

              tag=(HT+j)->weight;

              child=HT+j;

        f=(HT+j)->parent;

              while(f!=0)

              {

                     if((f->lchild)->weight==(f->rchild)->weight) *(cd+h)=child->dj;

                     else if((f->lchild)->weight==tag) *(cd+h)='0';//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                     else if((f->rchild)->weight==tag) *(cd+h)='1';//!!!!!!!!!注意这行,当父母结点的孩子结点weight都相等时,要做一些处理!!!!即用childf->dj来判断

                     else ;

                     h--;

            tag=f->weight;

                     child=flast=f;

                     f=f->parent;

              }

              strcpy(*(da+j),cd+h+1);

              *(HC+j)=*(da+j);

       }

       printf("the %d word's code is:\n",n);

       for(j=0;j<=N-1;j++) puts(*(HC+j));

//.............................................................................................................

    printf("enter the file's name:\n");//打开文件,读取字符,使得到与文件相关的编码,存在code[]

       gets(wj);

    if((fp=fopen(wj,"r"))==NULL)

       {

              printf("cannot open the file!\n");

              exit(0);

       }

    while(!feof(fp))

       {

              ch=fgetc(fp);

              for(j=0;j<=N-1;j++)

              {

                  if(ch==a[j])

                     {

                            strcat(code,*(HC+j));

                            break;

                     }

              }

       }

       printf("what should be sent is:\n");

       puts(code);

 

//.........................................................................................................

       tag=0;//根据发送过来的信息code[],破译得到mi[],mi[]即为实际想要发送过来的信息

       n=0;

       while(code[tag]!='\0')

       {

        f=flast;

              for(j=tag;code[j]!='\0';j++)

              {

                     if(code[j]=='0')

                     {

                            f=f->lchild;

                     }

                     if(code[j]=='1')

                     {

                            f=f->rchild;

                     }

                     if(f->rchild==0)

                     {

                            for(m=0;m<=N-1;m++)

                            {

                                   if((HT+m)->weight==f->weight)

                                   {

                                          h=m;

                                          break;

                                   }

                            }

                            mi[n++]=a[h];

                            break;

                     }

              }

              tag=j+1;

       }

       mi[n]='\0';

       printf("it has been translated:\n");

       puts(mi);

}

 

测试数据:

 

 

 

posted @ 2013-11-24 11:41  little white  阅读(937)  评论(0编辑  收藏  举报