链表解决约瑟夫环问题
约瑟夫环问题
(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);
}
测试数据: