【算法基础】循环链表解决约瑟夫问题

不多说了 直接贴代码了。 生成循环列表的方式有点儿恶心...

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

//定义常量
#define TRUE  1
#define FALSE 0

//类型别名
typedef int BOOL;

//定义节点
typedef struct Node
{
	int data; //数据
	struct Node * pNext;  //指针
} NODE , * PNODE ; // NODE == struct node , PNODE ==  struct node *



PNODE createList()
{
	int len;
	int i;
	int val;
	printf("请输入要生成链表的节点个数的节点个数:len=");
	scanf("%d",&len);

	PNODE pHead = (PNODE)malloc(sizeof(NODE));
	pHead->pNext = NULL; //设置指针域为空
	
	PNODE ret = NULL;

	//中间节点
	PNODE pTail = pHead;

	if(NULL == pHead){
		printf("动态分配内存失败...\n");
		exit(-1);
	}
	for(i=0;i<len;i++){
		printf("输入第%d个节点的值:",i+1);
		scanf("%d",&val);
		PNODE temp = (PNODE)malloc(sizeof(NODE));
		temp->data = val; //接收数值
		temp->pNext = NULL;
		pTail->pNext = temp; //设置头节点指针域
		pTail = temp;
	}
	//让链表有环
	pTail->pNext = pHead->pNext;

	ret = pHead->pNext;
	
	free(pHead);
	
	//返回头节点
	return ret;
}

//遍历链表 参数,链表的头节点
void traverseList(PNODE pHead)
{
	printf("traverseList func is start... \n");
	//printf("%d\n",pHead->data);
	PNODE p=pHead->pNext;
	while(p!=NULL){
		printf("%d \n",p->data);
		p = p->pNext;
	}
	printf("traverseList func is end... \n");
}

/*
约瑟夫环链表解决
*/

void killNode(PNODE pHead , int startPos, int killPos)
{
		int i , count = 1;
		PNODE p , temp = NULL;
		
		p = pHead;
		
		//找到起始位置
		for(i = 1; i < startPos ; i++)
		{
			p = p->pNext;
		}
		//printf("%d \n", p->data);
		
		while (p->pNext != p) {
			for (i = 1; i<killPos; i++)
			{
				temp = p;
				p = p->pNext;
			}
			temp->pNext = p->pNext;//让*temp指向*p后面的结点
			printf("第%d个出列的犹太人的编号为:%d\n", count, p->data);
			free(p);//释放*p
			count++;
			//出列者的下一个犹太人作为新的第一个报数者
			p = temp->pNext;
		}
		printf("第%d个出列的犹太人的编号为:%d\n", count, p->data);
		free(p);
		pHead = NULL;
}


int main(int argc, char *argv[]) {
	
	//定义头节点
	PNODE pHead = NULL; 
	
	//创建一个单链表
	pHead = createList(); 

	//traverseList(pHead);
	
	killNode(pHead, 1 , 2);
	
	return 0;
}

 

posted @ 2019-01-12 22:34  abs_征召不老  阅读(94)  评论(0)    收藏  举报