作业:循环链表--选班长

作业:循环链表--选班长

约瑟夫环问题

题目:有44人,从1开始报数,每次到3时淘汰那个人,重新开始从1报数,直到只有最后一人为止。
单链表---》循环链表

单链表的最后一个结点的next指向头结点 形成一个循环

//构建循环链表  最后一个结点的指向为head
	p->next = head;
获取最后1人

当p->next等于p时 表明只剩下1个节点

while (p->next!=p)//所以这里p->next!=p时 表明至少存在两个
	{
		//移动到待删除元素前一个
		while ((index+1)!=m)
		{
			p = p->next;
			index++;
		}
		index = 1;
		//打印待删除元素的信息
		//printf("%d \t", p->next->data);
		//执行链表上的删除 但是删除元素任然存在于内存中
		p->next = p->next->next;
		//删除后 移动到下一个重新开始报数c
		p = p->next;
	}
链表的反转

额外申请空间,当前node->next-next暂存起来

node->next的这个结点的next指向node

node* tmp,*orginHead=head, * newHead, *newTmp;
	newHead = head->next;
	tmp = head->next->next;//先记录下一个即将操作的节点
	//先反转一次 第二个节点的next指向原来的第一个节点
	head->next = NULL;
	newHead->next = head
完整的代码
#include <stdio.h>
#include <malloc.h>
//
//约瑟夫环问题
//

//循环链表
typedef struct Node {
	struct Node *next;
	int data;
}node;

node* initLinkList(int* arrStart,int len) {
	struct Node* head = (node*)malloc(sizeof(node)), * tmp, * p;
	p = head;
	head->data = *arrStart;
	for (int i = 1; i < len; i++) {
		tmp = (node*)malloc(sizeof(node));
		tmp->data = *(arrStart + i);
		tmp->next = NULL;
		p->next = tmp;
		p = p->next;
	}
	//构建循环链表  最后一个结点的指向为head
	p->next = head;
	return head;
}

/// <summary>
/// 链表反转 时间复杂度:O(n)
/// </summary>
/// <param name="head"></param>
/// <returns></returns>
node* linkListReverse(node* head) {
	node* tmp,*orginHead=head, * newHead, *newTmp;
	newHead = head->next;
	tmp = head->next->next;//先记录下一个即将操作的节点
	//先反转一次 第二个节点的next指向原来的第一个节点
	head->next = NULL;
	newHead->next = head;
	while (tmp!=head)
	{
		newTmp = tmp->next;
		tmp->next = newHead;
		newHead = tmp;
		tmp = newTmp;
	}
	head->next = newHead;//形成一个循环
	return newHead;
}

void displayLinkList(node* head,int n) {
	int count = 0;
	while (count<n)
	{
		printf("%d \t", head->data);
		head = head->next;
		count++;
	}
	printf("\n\n");
}

/// <summary>
/// 获取最后一个人  约瑟夫环问题
/// </summary>
/// <param name="n">n人</param>
/// <param name="m">第m人出局</param>
/// <returns>最后剩下的那个人</returns>
int GetLastRemain(node* head,int m) {
	node* p = head,*originHead=head;
	int index = 1;
	while (p->next!=p)
	{
		//移动到待删除元素前一个
		while ((index+1)!=m)
		{
			p = p->next;
			index++;
		}
		index = 1;
		//打印待删除元素的信息
		//printf("%d \t", p->next->data);
		//执行链表上的删除 但是删除元素任然存在于内存中
		p->next = p->next->next;
		//删除后 移动到下一个重新开始报数
		p = p->next;
	}
	return p->data;
}
int main() {
	int arrs[44] = { 761,762,770,774,775,800,807,825,826,842,849,879,884,885,892,893,896,900,903,912,947,951,955,959,
						962,965,970,977,978,980,1004,1008,1041,1045,1048,1050,1056,1057,1081,1082,1084,1088,1089,1121 };
	node* head = initLinkList(&arrs, 44);
	displayLinkList(head, 44);
	int p=GetLastRemain(head, 3);
	printf("\n%d\n\n", p);

	head = initLinkList(&arrs, 44);
	head=linkListReverse(head);
	displayLinkList(head, 44);
	p = GetLastRemain(head, 3);
	printf("\n%d\n\n", p);
	system("pause");
}
posted @ 2021-10-12 21:40  无涯ha  阅读(109)  评论(0编辑  收藏  举报