约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
// Count3Out.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<stdio.h>
#include <stdlib.h>
typedef struct node//节点存放一个数据和指向下一个节点的指针
{
int data;
struct node* pnext;
} Node;
Node *link_create(int n)//创建n个节点的循环链表
{
//先创建第1个节点
Node *p,*q,*head;
int i ;
p = (Node *)malloc(sizeof(Node));
head = p;
p->data = 1;
for(i = 2;i<=n;i++)//再创建剩余节点
{
q = (Node *)malloc(sizeof(Node));
q->data = i;
p->pnext = q;
p = q;
}
p->pnext = head;//最后一个节点指向头部,形成循环链表
return head;
}
Node* create_Link(int n)
{
Node* p,*q,*head;
int i=0;
p=(Node*)malloc(sizeof(Node));
head=p;
p->data=1;
for (int i=2;i<=n;i++)
{
q=(Node*)malloc(sizeof(Node));
q->data=i;
p->pnext=q;
p=q;
}
p->pnext=head;
return head;
}
void printf_Link(Node *head)
{
const Node* pCur = head;
if(head==NULL)
return ;
do
{
printf("%d->",pCur->data);
pCur=pCur->pnext;
} while (pCur!=head);
}
void link_process(Node *head,int k,int m)//从编号为k(1<=k<=n)的人开始报数,数到m的那个人出列;
{
int i;
Node *p = head,*tmp1,*tmp2;
while(p->data != k)//p指向的节点data为k
p = p->pnext;
while(p->pnext != p)
{
for(i=1;i<m;i++)
{
tmp1 = p;
p = p->pnext;
}
printf("%d ",p->data);
tmp1->pnext= p->pnext;
free(p);
p = tmp1->pnext;
}
printf("%d ",p->data);
free(p);
}
void countMOut(Node* head,int k,int m)
{
Node* p=head;
Node* temp;
while(p->data!=k)
p=p->pnext;
//如果找到第K个
while(p->pnext!=p)
{
for(int i=1;i<m;i++)
{
temp=p;
p=p->pnext;
}
printf("%d->",p->data);
temp->pnext=p->pnext;
free(p);
p=temp->pnext;
}
printf("%d",p->data);
free(p);
}
int main()
{
Node *head = create_Link(8);
//link_process(head,3,4);
printf("按序打印链表");
printf_Link(head);
printf("\n");
countMOut(head,3,4);
system("pause");
return 0;
}
结果如下
