学习笔记:数据结构与算法(六):线性表(4)_一位魔术师掏出一叠扑克牌,他取出其中13张黑桃 循环链表-程序员宅基地

技术标签: 数据结构学习  

学习笔记:数据结构与算法(六):线性表(4)

约瑟夫环

据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第3个人。接着,杀掉第3个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决。Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
约瑟夫问题和循环链表相同。
问题:用循环链表模拟约瑟夫问题,把41个人自杀的顺序编号输出。

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

typedef struct node
{
    
	int data;
	struct node *next;
}node;

node *create(int n)
{
    
	node *p = NULL, *head;
	head = (node*)malloc(sizeof(node));
	p = head;
	node *s;
	int i = 1;

	if( n != 0)
	{
    
		while(i<=n)
		{
    
			s = (node*)malloc(sizeof(node));
			s->data = i;
			i++;
			p->next = s;
			p = s;
		}
		s->next = head->next;//不指向头节点,而是第一个结点,构成一个环,释放头结点
	}
	free(head)
	return s->next;
}

int main()
{
    
	int n = 41;
	int m = 3;
	int i;
	node *p = create(n);
	node *temp;
	
	m %= n; //在这里是2
	while( p != p->next )
	{
    
		for(i = 1; i < m-1; i++)
		{
    
			p = p->next;
		}
		printf("%d -> ",p->next->data);
		
		temp = p->next;
		p->next = temp->next;
		free(temp);
		
		p = p->next;
	}
	printf("%d\n",p->data);
	return 0;
}

循环链表的改进

去掉头指针,将尾指针指向头结点

判断空链表的条件:rear是否等于rear->next。
例题1:实现将两个链表连接成一个线性表(a1, a2, a3…b1, b2…)的运算
普通思路:用头指针表示的单循环表上,遍历第一个链表,找到an,然后将b1放在an的后面,bn的next指向a的头结点。执行时间为O(n)
优化思路:只需要修改二者的尾指针
在这里插入图片描述
例题2:判断单链表中是否有环(链表的尾结点指向了链表中的某个结点)
在这里插入图片描述

方法一:使用p,q两个节点,p总是向前走,q是每次从头开始走,对于每个结点,看p的步数和q是否一样。例如,p从1-2-3-4-5-6-3,用了6步,此时q从head出发,只需要两步,因此步数不等,存在环。
方法二:快慢指针,p向前走一步,q走两步,某个时候p==q,则存在环。

魔术师发牌问题

一位魔术师掏出一叠扑克牌,魔术师取出其中13张黑桃,洗好后,把牌面朝下。说:“我不看牌,只数一数就能知道每张牌是什么?”魔术师口中念一,将第一张牌翻过来看正好是A;魔术师将黑桃A放到桌上,继续数手里的余牌,第二次数1,2,将第一张牌放到这叠牌的下面,将第二张牌翻开,正好是黑桃2,也把它放在桌子上。第三次数1,2,3,前面二张牌放到这叠牌的下面,取出第三张牌,正好是黑桃3,这样依次将13张牌翻出,全部都准确无误。求解:魔术师手中牌的原始顺序是什么样子的?
代码如下:

#include <stdio.h>
#include <stdlib.h>
#define CardNumber 13
typedef struct node
{
    
	int data;
	struct node *next;
}sqlist,*linklist;

linklist CreateLinkList()
{
    
	linklist head = NULL;
	linklist s, r;
	int i;
	
	r = head;
	for(i = 1; i<= CardNumber ; i++)
	{
    
		s = (linklist)malloc(sizeof(sqlist));
		s->data = 0;
		
		if(head == 	NULL)
			head = s;
		else 
			r->next = s;
		r=s;
	}
	r->next = head;
	return head;
}

//发牌顺序计算
void Magician(linklist head)
{
    
	linklist p;
	int j;
	int Countnumber = 2;

	p = head;
	p->data = 1; //第一张牌放1
	
	while(1)
	{
    
		for( j = 0 ;j <Countnumber ; j++)
		{
    
			p = p->next;
			if(p->data != 0)
			{
    
				p->next;
				j--;
			}
		}
		if(p->data == 0)
		{
    
			p->data = Countnumber;
			Countnumber++;
			if(Countnumber == 14)
				break;
		}
	}
}
int main()
{
    
	linklist p ;
	int i;
	p =  CreateLinkList();
	Magician(p);

	printf("排列顺序:\n");
	for(i = 0; i < CardNumber ; i++)
	{
    
		printf("黑桃%d", p->data);
		p = p->next;
	}
	return 0;
}

双向链表

结点结构

在这里插入图片描述
在这里插入图片描述

插入操作

在这里插入图片描述
在这里插入图片描述

删除操作

在这里插入图片描述
在这里插入图片描述

例题

要求实现用户输入一个数使得26个字母的排列发生变化,例如用户输入3,输出结果:DEFGHIJKLMNOPQRSTUVWXYZABC。也支持负数输入,例如-3,XYZABCDEFGHIJKLMNOPQRSTUVW
代码实现如下:

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

#define OK 1
#define ERROR 0
typedef char ElemType;
typedef int Status;

typedef struct DualNode
{
    
	ElemType data;
	struct DualNode *prior;
	struct DualNode *next;
}DualNode, *DuLinkList;

Status InitList(DuLinkList *L)
{
    
	DualNode *p,*q;
	int i;
	*L = (DuLinkList)malloc(sizeof(DualNode));
	if(!(*L))
		return ERROR;
	(*L)->next = (*L)->prior = NULL;
	p = (*L);
	for(i = 0; i < 26; i ++)
	{
    
		q = (DuLinkList)malloc(sizeof(DualNode));
		if(!q)
			return ERROR;
		q->data = 'A' + i;
		q->prior = p;
		q->next = p->next;
		p->next = q;
		p = q; 
	}
	p->next = (*L)->next;
	(*L)->next->prior = p;
	return OK;
}

void Caesar(DuLinkList *L, int i)
{
    
	if( i > 0)
	{
    
		do
		{
    
			(*L) = (*L)->next;
		}while( --i);
	}
	if( i < 0)
	{
    
		do
		{
    
			(*L) = (*L)->next;
		}while( ++i);
	}
}
int main()
{
    
	DuLinkList L;
	int i,n ;
	InitList(&L);
	
	printf("请输入一个整数:");
	scanf("%d",&n);
	printf("\n");
	
	Caesar(&L ,n );
	
	for(i = 0; i< 26 ;i ++)
	{
    
		L = L->next;
		printf("%c", L->data);
	}
	return 0;
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lelelewei/article/details/114549187

智能推荐

FX3/CX3 JLINK 调试_ezusbsuite_qsg.pdf-程序员宅基地

文章浏览阅读2.1k次。FX3 JLINK调试是一个有些麻烦的事情,经常有些莫名其妙的问题。 设置参见 c:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\doc\firmware 下的 EzUsbSuite_UG.pdf 文档。 常见问题: 1.装了多个版本的jlink,使用了未注册或不适当的版本 选择一个正确的版本。JLinkARM_V408l,JLinkA_ezusbsuite_qsg.pdf

用openGL+QT简单实现二进制stl文件读取显示并通过鼠标旋转缩放_qopengl如何鼠标控制旋转-程序员宅基地

文章浏览阅读2.6k次。** 本文仅通过用openGL+QT简单实现二进制stl文件读取显示并通过鼠标旋转缩放, 是比较入门的级别,由于个人能力有限,新手级别,所以未能施加光影灯光等操作, 未能让显示的stl文件更加真实。****效果图:**1. main.cpp```cpp#include "widget.h"#include <QApplication>int main(int argc, char *argv[]){ QApplication a(argc, argv); _qopengl如何鼠标控制旋转

刘焕勇&王昊奋|ChatGPT对知识图谱的影响讨论实录-程序员宅基地

文章浏览阅读943次,点赞22次,收藏19次。以大规模预训练语言模型为基础的chatgpt成功出圈,在近几日已经给人工智能板块带来了多次涨停,这足够说明这一风口的到来。而作为曾经的风口“知识图谱”而言,如何找到其与chatgpt之间的区别,找好自身的定位显得尤为重要。形式化知识和参数化知识在表现形式上一直都是大家考虑的问题,两种技术都应该有自己的定位与价值所在。知识图谱构建往往是抽取式的,而且往往包含一系列知识冲突检测、消解过程,整个过程都能溯源。以这样的知识作为输入,能在相当程度上解决当前ChatGPT的事实谬误问题,并具有可解释性。

如何实现tomcat的热部署_tomcat热部署-程序员宅基地

文章浏览阅读1.3k次。最重要的一点,一定是degbug的方式启动,不然热部署不会生效,注意,注意!_tomcat热部署

用HTML5做一个个人网站,此文仅展示个人主页界面。内附源代码下载地址_个人主页源码-程序员宅基地

文章浏览阅读10w+次,点赞56次,收藏482次。html5 ,用css去修饰自己的个人主页代码如下:&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;&lt;html xmlns="http://www.w3.org/1999/xh..._个人主页源码

程序员公开上班摸鱼神器!有了它,老板都不好意思打扰你!-程序员宅基地

文章浏览阅读201次。开发者(KaiFaX)面向全栈工程师的开发者专注于前端、Java/Python/Go/PHP的技术社区来源:开源最前线链接:https://github.com/svenstaro/gen..._程序员怎么上班摸鱼

随便推点

UG\NX二次开发 改变Block UI界面的尺寸_ug二次开发 调整 对话框大小-程序员宅基地

文章浏览阅读1.3k次。改变Block UI界面的尺寸_ug二次开发 调整 对话框大小

基于深度学习的股票预测(完整版,有代码)_基于深度学习的股票操纵识别研究python代码-程序员宅基地

文章浏览阅读1.3w次,点赞18次,收藏291次。基于深度学习的股票预测数据获取数据转换LSTM模型搭建训练模型预测结果数据获取采用tushare的数据接口(不知道tushare的筒子们自行百度一下,简而言之其免费提供各类金融数据 , 助力智能投资与创新型投资。)python可以直接使用pip安装tushare!pip install tushareCollecting tushare Downloading https://files.pythonhosted.org/packages/17/76/dc6784a1c07ec040e74_基于深度学习的股票操纵识别研究python代码

中科网威工业级防火墙通过电力行业测评_电力行业防火墙有哪些-程序员宅基地

文章浏览阅读2k次。【IT168 厂商动态】 近日,北京中科网威(NETPOWER)工业级防火墙通过了中国电力工业电力设备及仪表质量检验测试中心(厂站自动化及远动)测试,并成为中国首家通过电力协议访问控制专业测评的工业级防火墙生产厂商。   北京中科网威(NETPOWER)工业级防火墙专为工业及恶劣环境下的网络安全需求而设计,它采用了非X86的高可靠嵌入式处理器并采用无风扇设计,整机功耗不到22W,具备极_电力行业防火墙有哪些

第十三周 ——项目二 “二叉树排序树中查找的路径”-程序员宅基地

文章浏览阅读206次。/*烟台大学计算机学院 作者:董玉祥 完成日期: 2017 12 3 问题描述:二叉树排序树中查找的路径 */#include #include #define MaxSize 100typedef int KeyType; //定义关键字类型typedef char InfoType;typedef struct node

C语言基础 -- scanf函数的返回值及其应用_c语言ignoring return value-程序员宅基地

文章浏览阅读775次。当时老师一定会告诉你,这个一个"warning"的报警,可以不用管它,也确实如此。不过,这条报警信息我们至少可以知道一点,就是scanf函数调用完之后是有一个返回值的,下面我们就要对scanf返回值进行详细的讨论。并给出在编程时利用scanf的返回值可以实现的一些功能。_c语言ignoring return value

数字医疗时代的数据安全如何保障?_数字医疗服务保障方案-程序员宅基地

文章浏览阅读9.6k次。十四五规划下,数据安全成为国家、社会发展面临的重要议题,《数据安全法》《个人信息保护法》《关键信息基础设施安全保护条例》已陆续施行。如何做好“数据安全建设”是数字时代的必答题。_数字医疗服务保障方案

推荐文章

热门文章

相关标签