用循环链表实现约瑟夫问题

来源:互联网 发布:javascript 添加元素 编辑:程序博客网 时间:2024/05/09 09:30

 

约瑟夫问题是个有名的问题:N个人围成一圈,从第K个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=8,M=4, K=3,被杀掉的人的序号为6,2,7,3,5,1,8。

 

joseph.h

 

#ifndef __JOSEPH_H__#define __JOSEPH_H__#define N 8     //人数为8#define K 3//从第3个人开始#define M 4//数到4extern void joseph(void);#endif


joseph.c

 

 

#include "joseph.h"#include "../list/listlinkloop.h"#include <stdio.h>#include <stdlib.h>void joseph(void){listlinkloop *l = listcreate();listlinkloop *temp1, *temp2;int i;for(i=1; i<=N; i++){listinserttail(l, i);    //插入初始时的数据}temp1 = listcuthead(l); //将循环链表的头去掉,因为头部不含有有效数据for(i=1; i<K; i++){temp1 = temp1->next;    //找到从哪个人开始,例如 从1-->2-->3-->4,从1到3经过2次循环。}while(temp1->next != temp1)    //当temp1->next 等于temp1时,只剩下一个元素{for(i=2; i<M; i++){temp1 = temp1->next;       // 例如从第3个人开始,3-->4-->5-->6,即6数到数字4,因为6要出栈,所以temp应该指向5才行,否则无法接上}temp2 = temp1->next;          //temp2指向元素6的位置temp1->next = temp2->next;   //跳过6,使5接上7printf("%d ", temp2->data);free(temp2);//释放6temp1 = temp1->next;//从元素7开始数}printf("%d\n", temp1->data);free(temp1);}

 

listlinkloop.h

#ifndef __LISTLINKLOOP_H__#define __LISTLINKLOOP_H__typedef int listdata;typedef struct list{listdata data;struct list *next;}listlinkloop;extern listlinkloop *listcreate(void);extern void listinserttail(listlinkloop *l, listdata data);extern void listprintf(listlinkloop *l);extern listlinkloop *listcuthead(listlinkloop *l);extern void listprintfloop(listlinkloop *l);#endif


 

listlinkloop.c

 

#include "listlinkloop.h"#include <stdlib.h>#include <stdio.h>listlinkloop *listcreate(void){listlinkloop *l = (listlinkloop *)malloc(sizeof(listlinkloop));l->next = l;return l;}void listinserttail(listlinkloop *l, listdata data){listlinkloop *temp1 = (listlinkloop *)malloc(sizeof(listlinkloop)), *temp2 = l;temp1->data = data;temp1->next = l; while(temp2->next != l){temp2 = temp2->next;}temp2->next = temp1;}listlinkloop *listcuthead(listlinkloop *l){listlinkloop *temp = l;while(temp->next != l){temp = temp->next;}temp->next = l->next;free(l);return temp->next;}void listprintf(listlinkloop *l){listlinkloop *temp = l;while(temp->next != l){printf("%d ", temp->next->data);temp = temp->next;}printf("\n");}void listprintfloop(listlinkloop *l){listlinkloop *temp = l;printf("%d ", temp->data);while(temp->next != l){printf("%d ", temp->next->data);temp = temp->next;}printf("\n");}


 

 

 


 

原创粉丝点击