首页 > 代码库 > 约瑟夫问题--循环链表实现

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

问题描述:

n 个人围成一个圆圈, 首先第 1 个人从 1 开始一个人一个人的顺时针报数,报到第 报到第 m 个人, 令其出列。 然后再从下一 个人开始从 1 顺时针报数 , 报到第 m 个人,  再令其出列,如此下去 , 求出列顺序。

头文件:

#ifndef _CIRCLE_H_
#define _CIRCLE_H_
//采用数据封装的方式,防止在主函数修改其中的属性值(有点点像面向对象中的私有属性)
typedef void CircleList;
typedef struct CircleListNode   //声明指针域
{
	CircleListNode * next;
}CircleListNode;

CircleList * CircleList_Create();

void CircleList_DesTroy(CircleList * list);

void CircleList_Clear(CircleList* list);

int CircleList_Length(CircleList* list);

int CircleList_Insert(CircleList* list, CircleListNode* node, int pos);

CircleListNode* CircleList_Get(CircleList* list, int pos);

CircleListNode* CircleList_Delete(CircleList* list, int pos);

CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node);

CircleListNode* CircleList_Reset(CircleList* list);

CircleListNode* CircleList_Current(CircleList* list);

CircleListNode* CircleList_Next(CircleList* list) ;

#endif 

源文件:

// 循环链表.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <malloc.h>
#include <stdlib.h>
#include "CircleList.h"

typedef struct   //定义头结点
{	   
   CircleListNode header;
   CircleListNode* sLider;  //游标
   int len;
}TCircleList;

struct Value        //定义数据结构体类型
{
	
    CircleListNode header;  //指针域
    int v;                //数据域
};




int _tmain(int argc, _TCHAR* argv[])
{	
	
	int i = 0;
	int m,n;
    CircleList* list = CircleList_Create();
    
    
	printf("约瑟夫问题: \n");
	printf("请输入总人数n:");
	scanf_s("%d",&n);
	printf("\n请输入数到第几个人就停止(使其退出)m:");
	scanf_s("%d",&m);
	struct Value valueArr[1000];
	for ( i=1; i<=n; i++)
	{
		valueArr[i].v = i;
		CircleList_Insert(list, (CircleListNode*)(&(valueArr[i])), CircleList_Length(list));
	}	
	printf("初始数据:\n");
	for(i=0; i<CircleList_Length(list); i++)
    {
		struct Value* pv = (struct Value*)CircleList_Next(list);
        
        printf("%d\n", pv->v);
    }
    
   printf("\n");
    
    CircleList_Reset(list);
	
    
    while( CircleList_Length(list) > 0 )
    {
        struct Value* pv = NULL;
        
        for(i=1; i<m; i++)
        {
            CircleList_Next(list);
        }
        
        pv = (struct Value*)CircleList_Current(list);
        
		printf("%d\n", pv->v);
        
        CircleList_DeleteNode(list, (CircleListNode*)pv);
    }





    CircleList_DesTroy(list);

	system("pause");
	return 0;
}

//创建
CircleList * CircleList_Create()
{
	TCircleList* list = (TCircleList*)malloc(sizeof(TCircleList));	
	if(NULL != list)
	{		
		list->sLider = NULL;
		list->header.next = NULL;
		list->len = 0;
		
	}
	return list;
}

//销毁
void CircleList_DesTroy(CircleList * list)
{
	free(list);
}
//清空
void CircleList_Clear(CircleList* list)
{
	TCircleList * sList = (TCircleList*)list;
	if(NULL != sList)
	{
		sList->len = 0;
		sList->header.next = NULL;
		sList->sLider = NULL;
	}
}
//获得长度
int CircleList_Length(CircleList* list)
{
	TCircleList * sList = (TCircleList*)list;
	int len = -1;
	if(NULL != sList)
	{
		len = sList->len;
	}
	return len;
}
//插入
int CircleList_Insert(CircleList* list, CircleListNode* node, int pos)
{
	TCircleList * sList = (TCircleList*)list;
	int i = 0;
	int ret = 0;
	sList->len;
	if((NULL != sList) && (pos>=0) && (NULL != node))
	{
		CircleListNode * current = (CircleListNode*)sList;
		for ( i=0; i<pos && current->next != NULL; i++)
		{
			current = current->next;
		}
		
		node->next = current->next;		
		current->next = node;
		if(sList->len == 0)
		{
			sList->sLider = node;
			node->next = node;
		}
		++(sList->len);
		ret = 1;
		
		
	}
   return ret;
}
//获得结点
CircleListNode* CircleList_Get(CircleList* list, int pos)
{
	TCircleList * sList = (TCircleList*)list;
	CircleListNode * resNode = NULL;
	int i = 0;
	if((NULL != sList) && (pos>=0))
	{
		CircleListNode * current = (CircleListNode*)sList;
		for( i=0; i<pos; i++)
		{
			//i=0时,current为头结点,current->next为真正的第一个结点
			current = current->next;
		}
		resNode = current->next;
	}
	return resNode;
}

//删除
CircleListNode* CircleList_Delete(CircleList* list, int pos)
{
	TCircleList * sList = (TCircleList*)list;
	int i = 0;
	CircleListNode * resnode = NULL;
	CircleListNode* first = sList->header.next;
	CircleListNode* last = (CircleListNode*)CircleList_Get(list,sList->len-1);
	if((NULL != sList) && (pos >= 0) && (pos < sList->len))
	{
		CircleListNode * current = (CircleListNode*)sList;
		for ( i=0; i<pos; i++)
		{
			//i=0时,current为头结点,current->next为真正的第一个结点
			current = current->next;
		}
		resnode = current->next;
		current->next = resnode->next;

		if(first == resnode)
		{
			sList->header.next = first->next;
			last->next = first->next;
		}
		if(sList->sLider == resnode)
		{
			sList->sLider = resnode->next;
		}
		if(sList->len == 0)
		{
			sList->header.next = NULL;
			sList->sLider = NULL;
		}
	}
	sList->len--;
	return resnode;
}

//根据结点来删除
CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node)
{
	TCircleList * sList = (TCircleList*)list;
	CircleListNode* resnode = NULL;
	int i = 0;
	if(NULL != sList)
	{
		CircleListNode* current = (CircleListNode*)sList;
		for ( i=0; i<sList->len; i++)
		{
			if(node == current->next)
			{
				resnode = current->next;
				break;
			}
			current = current->next;
		}
		if(NULL != resnode)
		{
			CircleList_Delete(sList,i);
		}
	}
	return resnode;
}


//将游标重置回第一个元素
CircleListNode* CircleList_Reset(CircleList* list) 
{
    TCircleList* sList = (TCircleList*)list;
    CircleListNode* ret = NULL;
    
    if( sList != NULL )
    {
		sList->sLider= sList->header.next;
        ret = sList->sLider;
    }
    
    return ret;
}

//获得当前游标下的结点
CircleListNode* CircleList_Current(CircleList* list) 
{
	
    TCircleList* sList = (TCircleList*)list;
    CircleListNode* ret = NULL;
	sList->len;
	sList->header;
	sList->sLider;
    if( sList != NULL )
    {
		ret = sList->sLider;
    }
    
    return ret;
}


//将游标移到下一个结点并获得当前移动前的结点
CircleListNode* CircleList_Next(CircleList* list) 
{
    TCircleList* sList = (TCircleList*)list;
    CircleListNode* ret = NULL;
    
	if( (sList != NULL) && (sList->sLider != NULL) )
    {
        ret = sList->sLider;
        sList->sLider = ret->next;
    }
    
    return ret;
}

运行结果:

约瑟夫问题:
请输入总人数n:6

请输入数到第几个人就停止(使其退出)m:7
初始数据:
1
2
3
4
5
6

1
3
6
2
4
5
请按任意键继续. . .


这样就欧啦~~~~


如有错误,望不吝指出。