您的位置:首页 > 其它

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

2013-02-21 20:11 537 查看
约瑟夫问题是个有名的问题: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	//数到4

extern 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接上7
		printf("%d ", temp2->data);
		free(temp2);										//释放6
		temp1 = 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");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: