约瑟夫环的应用

//1、使用结构体创建一个结点,结点内容包括一个指向下一个结点的指针和一个int类型的数据
//2、使用一个字符数组创建单链表
//3、将单链表构造成循环单链表,使用一个指针从头遍历单链表,直到这个指针指向最后一个结点,将这个结点的指针域指向头结点
//4、实现约瑟夫环
//   1)、从当前结点的下一个结点报数,直到找到报数是m的结点,将当前结点的值交给m,使用替换法输出并删除当前结点
//   2)、循环处理1),直到约瑟夫环中只剩下一个结点,直接将最后一个结点的值打印出来


//使用结构体创建一个结点,结点内容包括一个指向下一个结点的指针和一个int类型的数据
typedef struct SListNode{
	struct SListNode* _next;
	int _data;
}Node, *pNode;				


//创建一个新的结点
pNode BuyNewNode(int data)
{
	pNode NewNode =(pNode)malloc(sizeof(Node));//申请一个结构体大小的空间
	assert(NewNode);                           //判断申请是否成功
	NewNode->_data = data;                     //给当前空间赋值
	NewNode->_next = NULL;
	return NewNode;                            //返回当前结点
}

//使用array整形数组循环创建一个单链表
pNode CreateList(int array[], int len)
{
	int i = 0;
	pNode pHead = NULL;
	pHead = BuyNewNode(array[0]);//给头结点赋一个初值
	pNode cur = pHead;
	for (i = 1; i < len; i++)    
	{
		pHead->_next = BuyNewNode(array[i]);//使用一个字符数组循环创建单链表
		pHead = pHead->_next;
	}
	return cur;
}

//实现约瑟夫环
void JosephCircle(pNode pHead, int m)
{
	int count = 0;
	pNode cur = pHead, tail = pHead;//tail尾指针
	pNode str = NULL;
	if (pHead == NULL)
		return;
	while (tail->_next != NULL)  //使用一个指针从头遍历单链表,直到这个指针指向最后一个结点,
		tail = tail->_next;
	tail->_next = pHead;         //将这个结点的指针域指向头结点

	count = m;                   //给count一个初始值m
	while (cur->_next != cur)
	{
		count = 1;               //从当前结点的下一个结点报数,直到找到报数是m的结点
		while (count != m)
		{
		  cur = cur->_next;
		  count++;
		}
		//替换法删除结点:将下一个结点的值赋给当前结点,然后将当前结点指向下一个结点的下一个结点,删除当前结点的下一个结点
		str = cur->_next;        
		count = cur->_data;         //将当前结点的值交给m
		printf("%d ", cur->_data);  //输出当前结点的值

		cur->_data = str->_data;    //替换法删除节点,
		cur->_next = str->_next;
		free(str);
	}
	printf("%d ", cur->_data);
}

int main()
{
	int array[] = { 3, 1, 7, 2, 4, 6, 5 };
	pNode pHead = CreateList(array, sizeof(array) / sizeof(array[0]));
	JosephCircle(pHead, 20);
	return 0;
}

约瑟夫环的应用_第1张图片

你可能感兴趣的:(编程语言)