约瑟环问题(全部代码在本文下方)

用循环链表编程实现约瑟夫问题,n个人围成一圈,从某人开始报数1,2,.., m,数到m的人出圈,然后从出圈的下一个人(m+1)开始重复此过程,直到全部人出圈,于是得到一个出圈人员的新序列,如当n=8,m=4时,若从第一个位置数起,则所得到的新的序列为4,8,5,2,1,3,7,6。

//约瑟环问题
void josepho(LoopLink *l,int k){
	if(NULL==l || list_empty(l) || k<0 ){
		printf("所给链表不合法或所给数太小,无法解决问题\n");
		return;
	}
	int n=l->len; //循环次数,n个人循环n次
	LoopLink *p=list_kill_head(l); //对链表进行去头操作
	l=NULL;
	LoopLink *q;  //定义指针,用来标记删除的结点
	for(int i=0;i<n;i++){
		for(int j=1;j<k-1;j++){
			p=p->next;
		}
		q=p->next;
		printf("%d\t",q->data);
		p->next=q->next;
		free(q);
	}
	putchar(10);
}

运行结果:

主函数代码:

#include <stdio.h>
#include "looplist.h"

int main(int argc, const char *argv[])
{
	//创建
	LoopLink *l=list_create();
	if(NULL==l){
		printf("创建失败\n");
		return 0;
	}
	//头插
	list_insert_head(l,1);
	list_insert_head(l,3);
	list_insert_head(l,5);
	list_insert_head(l,7);
	list_insert_head(l,9);
	list_display(l);
	//约瑟环问题
	josepho(l,3);
	return 0;
}

定义函数代码:

#include <stdio.h>
#include <stdlib.h>
#include "looplist.h"

//创建
LoopLink *list_create(){
	LoopLink *l=(LoopLink *)malloc(sizeof(LoopLink));
	if(NULL==l){
		printf("创建失败\n");
		return NULL;
	}
	//初始化
	l->len=0;
	l->next=l;//将指针指向自己
	printf("创建成功\n");
	return l;
}

//判空
int list_empty(LoopLink *l){
	return l->next==l;
}

//头插
int list_insert_head(LoopLink *l,datatype e){
	if(NULL==l){
		printf("所给链表不合法\n");
		return 0;
	}

	//申请结点封装数据
	LoopLink *p=(LoopLink *)malloc(sizeof(LoopLink));
	if(NULL==p){
		printf("结点申请失败\n");
		return 0;
	}
	p->data=e;
	p->next=NULL;

	//头插
	p->next=l->next;
	l->next=p;

	l->len++;
	printf("插入成功\n");
	return 1;
}

//遍历
void list_display(LoopLink *l){
	if(NULL==l || list_empty(l)){
		printf("遍历失败\n");
		return;
	}
	LoopLink *q=l->next;
	while(q!=l){
		printf("%d\t",q->data);
		q=q->next;
	}
	putchar(10);
}
//头删
int list_delete_head(LoopLink *l){
	if(NULL==l || list_empty(l)){
		printf("删除失败\n");
		return 0;
	}
	LoopLink *q=l->next;
	l->next=q->next;
	free(q);
	q=NULL;
	l->len--;
	printf("删除成功\n");
	return 1;
}
//删除头结点
LoopLink *list_kill_head(LoopLink *l){
	if(NULL==l || list_empty(l)){
		printf("去头失败\n");
		return 0;
	}
	//定义遍历指针指向最后一个结点
	LoopLink *q=l->next;
	while(q->next!=l){
		q=q->next;
	}
	q->next=l->next;
	free(l);
	l=NULL;
	printf("去头成功\n");
	return q->next;
}
//删除头结点后的遍历
void list_display_noh(LoopLink *h){
	if(NULL==h){
		printf("遍历失败\n");
		return;
	}
	LoopLink *q=h;
	do{
		printf("%d\t",q->data);
		q=q->next;
	}while(q != h);
	putchar(10);
}
//约瑟环问题
void josepho(LoopLink *l,int k){
	if(NULL==l || list_empty(l) || k<0 ){
		printf("所给链表不合法或所给数太小,无法解决问题\n");
		return;
	}
	int n=l->len; //循环次数,n个人循环n次
	LoopLink *p=list_kill_head(l); //对链表进行去头操作
	l=NULL;
	LoopLink *q;  //定义指针,用来标记删除的结点
	for(int i=0;i<n;i++){
		for(int j=1;j<k-1;j++){
			p=p->next;
		}
		q=p->next;
		printf("%d\t",q->data);
		p->next=q->next;
		free(q);
	}
	putchar(10);
}

 头文件:

#ifndef __LOOPLIST_H__
#define __LOOPLIST_H__

typedef int datatype;
typedef struct Node
{
    union{
        int len;          //头结点数据域
        datatype data;     //普通节点数据域    
    };
    struct Node *next;         //指针域
}LoopLink;

//创建
LoopLink *list_create();
//判空
int list_empty(LoopLink *l);
//头插
int list_insert_head(LoopLink *l,datatype e);
//遍历
void list_display(LoopLink *l);
//头删
int list_delete_head(LoopLink *l);
//删除头结点
LoopLink *list_kill_head(LoopLink *l);
//删除头结点后的遍历
void list_display_noh(LoopLink *h);
//约瑟环问题
void josepho(LoopLink *l,int k);

#endif

Makefile:

TARGET:=a.out

OBJS:=looplist.o main.o

CC:=gcc

CFLAGS:=-o

CFLAGSs:=-c -o

$(TARGET):$(OBJS)
	$(CC) $(OBJS) $(CFLAGS) $(TARGET)

%.o:%.c
	$(CC) $*.c $(CFLAGSs) $*.o

.PHONY:clean
clean:
	rm *.o a.out

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值