【蓝桥杯冲击国赛计划第2天】双向链表、循环链表 {题目:小王子链表、约瑟夫环}

news/2024/11/22 22:48:42/

文章目录

  • 1. 双向链表
    • 1.1 概念
    • 1.2 结点的定义
    • 1.3 实例「小王子链表」
      • 题目描述
      • 输入描述
      • 输出描述
      • 输入输出样例
        • 示例 1
      • 运行限制
    • 1.4 链表初始化
    • 1.5 链表插入
    • 1.6 链表删除
    • 1.7 链表打印
    • 1.8 主函数
  • 2. 循环链表
    • 2.1 概念
    • 2.2 结点的定义
    • 2.3 实例「约瑟夫环」
      • 题目描述
      • 输入描述
      • 输出描述
      • 输入输出样例
        • 示例 1
      • 运行限制
    • 2.4 简单分析
    • 2.5 链表初始化
    • 2.6 链表模拟过程(主函数)
      • 2.6.1 输入数据
      • 2.6.2 循环遍历 p 到第一次 k 的位置
      • 2.6.3 模拟
  • 3. 完整代码

在这里插入图片描述

1. 双向链表

1.1 概念

单向链表我们只能从一个方向找我想要的结点,而双向链表可以双向找我想要的结点。就比如在只用一个变量遍历链表中的元素时,我们发现到了要删的元素的时候,无法得到他的上一个元素,而双向链表就可以在使用一个变量遍历链表时得到前面的元素。

事实上,单向链表也可以用一个变量遍历元素做到删减的功能,等下在循环链表有应用。

双向链表数据域,左指针域和右指针域组成。

在这里插入图片描述

相互连接关系为:

在这里插入图片描述

前一个结点的右指针指向后一个结点,后一个结点的左指针指向前一个结点。

我们暂时先将结点简化为:

在这里插入图片描述


1.2 结点的定义

根据 python 类的定义双向链表的结点:

class Node:def __init__(self,value,left=None,right=None):self.value = valueself.left = leftself.right = right

1.3 实例「小王子链表」

我们还是通过这个实例来了解一下,双向链表的定义和使用。


题目描述

小王子有一天迷上了排队的游戏,桌子上有标号为 1−10 的 10 个玩具,现在小王子将他们排成一列,可小王子还是太小了,他不确定他到底想把那个玩具摆在哪里,直到最后才能排成一条直线,求玩具的编号。已知他排了 M 次,每次都是选取标号为 X 个放到最前面,求每次排完后玩具的编号序列。

输入描述

第一行是一个整数 M,表示小王子排玩具的次数。

随后 M 行每行包含一个整数 X,表示小王子要把编号为 X 的玩具放在最前面。

输出描述

M 行,第 i 行输出小王子第 i 次排完序后玩具的编号序列。

输入输出样例

示例 1

输入

5
3
2
3
4
2

输出

3 1 2 4 5 6 7 8 9 10
2 3 1 4 5 6 7 8 9 10
3 2 1 4 5 6 7 8 9 10
4 3 2 1 5 6 7 8 9 10
2 4 3 1 5 6 7 8 9 10

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

1.4 链表初始化

先右连接下一个,再左连接上一个(左连接这里用的是需要用建立好的连接先从右连接到下一个结点,然后再用左连接连接到上一个结点)

def createLink(): # 创建链表head = Node(0)p = headfor i in range(1,11):p.right = Node(i) # 右连接下一个p.right.left = p # 左连接上一个p = p.right # 移动return head

1.5 链表插入

欲在头结点和结点1之间插入结点5,注意以下只是其中一种插入方法

在这里插入图片描述

  • 结点5和结点1的连接
    结点5和结点1先建立右连接,然后结点1与结点5建立左连接,与此同时,结点1到头结点的左连接中断

  • 头结点和结点5的连接
    头结点建立与结点5的右连接时,头结点到结点1的右连接中断,至此头结点与结点1没有任何连接,最后,结点5左连接头结点。

  • 插入的代码

    def insertLink(x,head): # 插入x元素p = Node(x)p.right = head.right # 插入的结点建立右连接p.right.left = p # 再建立其左连接head.right = p # 头和插入结点建立右连接p.left = head # 再建立其左连接return head
    

1.6 链表删除

注意以下只是其中一种删除方法,代码采用的是先建立左连接,再建立右连接的方法

在这里插入图片描述

  • 先建立右连接

    若结点 i 与 i+2 建立右连接,则结点 i 与待删除结点的右连接中断

  • 再建立左连接

    若结点 i+2 与 i 建立左连接,则结点 i+2 与待删除结点的左连接中断

  • 删除的代码

    def deleteLink(x,head): # 删除x元素p = headwhile p != None:if p.value == x:p.right.left = p.left # 建立左连接p.left.right = p.right # 建立右连接p = p.rightreturn head
    

1.7 链表打印

和单向链表一样,不过使用 right 指向下一个

def showLink(head):p = head.rightwhile p!= None:print(p.value,end=" ")p = p.rightprint("")

1.8 主函数

这里一定要先删除后插入,因为先插入再删除,会把插入的那个给删了,这和我们的目的不符。

if __name__ == '__main__':head = createLink()n = int(input())for i in range(n):x = int(input())deleteLink(x,head)insertLink(x,head)showLink(head)

2. 循环链表

2.1 概念

我们将单向链表的头结点和尾结点相连,就组成了新的一种链表,循环链表。(我们这里一般较少用双向链表去建立循环链表,因为他的删除和加入和结点结构都比单向链表复杂)。

循环链表的结构:

在这里插入图片描述


2.2 结点的定义

由于由单向链表组成,所以结点的定义并无区别。

class Node:def __init__(self,value,next=None):self.value = valueself.next = next

2.3 实例「约瑟夫环」

我们通过这个实例来了解一下,循环链表的定义和使用。


题目描述

设有 n 个人围坐在圆桌周围,现从某个位置 k 上的人开始报数,报数到 m 的人就站出来。下一个人,即原来的第 m+1 个位置上的人,又从 1 开始报数,再报数到 m 的人站出来。依次重复下去,直到全部的人都站出来为止。试设计一个程序求出这 n 个人的出列顺序。

在这里插入图片描述

要求一:采用循环链表解决。

要求二:可以使用模拟法,模拟循环链表。

要求三:可以不使用循环链表类的定义使用方式。

输入描述

输入只有一行且为用空格隔开的三个正整数 n,k,m,其含义如上所述。

输出描述

n 行,表示这 n 个人的出列顺序。

输入输出样例

示例 1

输入

3 5 8

输出

3
2
1

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

2.4 简单分析

如果使用数组也能做,要不就是删除数组中的元素(需要进行多次移动),要不就是设置一个标记出列的为 0 ,未出列的为 1,但这可能需要频繁判断数组元素是否出列。所以这里还是采用循环链表来做。

2.5 链表初始化

和单向链表一致,只是尾结点连接的不再是 none,而是 head,注意这里:头结点并不再是无意义的数值,而是有数据元素的结点,也就是没有头结点这个说法了,而是首元结点: 单链表中第一个有数据元素的结点。

在初始化时我们也要注意 <1 个结点肯定构不成链表,而 1 个结点没必要用循环链表,再怎么循环都是它自己,所以我们先判断再连接。

def createLink(n):# 先判断if n <= 0:return Falseelif n == 1:return Node(1)else:head = Node(1)p = headfor i in range(2,n+1):p.next = Node(i)p = p.nextp.next = head # 首尾相接return head

2.6 链表模拟过程(主函数)

2.6.1 输入数据

我们可以通过 map 函数输入 n,k,m,然后创建循环列表,并定义遍历变量 p

n,k,m = map(int,input().split())
head = createLink(n)
p = head

2.6.2 循环遍历 p 到第一次 k 的位置

从结点 1 到结点 k 需要移动 k-1 步

## 先到k的位置
for i in range(k-1):p = p.next

2.6.3 模拟

我们移动后的步骤应该就是删除了,由于我们使用的是一个变量的遍历,他一定在待删除结点的上一个结点,所以约舍夫环出队的元素应该在该变量的下一个结点里。如果我们只剩一个结点,即它根据定义应该是待删除结点的上一个结点,当打印出队元素的时候会是空,所以应该在删除之前加上一个循环判定,如果结点不是链表中最后的结点,执行删除和打印操作。

while p.next != p: # p 不是最后的结点

我们从刚才的模拟过程应该知道:p 是待删除结点的上一个结点,所以应该报数到 m-1 ,而报数 m-1 需要移动 m-2次(如报数 3,1 到 3 只需移动 2 步)

for i in range(m-2): # 找到该删除指针的上一个指针p = p.next

这时候我们指向要删除的上一个结点,所以我们先打印出来

print(p.next.value) 

再进行删除操作:

p.next = p.next.next # 连接
p = p.next # 重新从1开始报数

由于之前我们的循环判断的是:p 不是最后的结点,所以跳出循环还有一个结点,我们也要打印出来。

print(p.value)

3. 完整代码

可在 我的仓库免费查看,如果无法使用可以及时私信我或在评论区指出,谢谢。

本文主要参考蓝桥杯省赛14天夺奖冲刺营,有兴趣的可以自己在蓝桥杯官网搜索

如有错误,敬请指正,欢迎交流🤝,谢谢♪(・ω・)ノ


http://www.ppmy.cn/news/624131.html

相关文章

快乐王子

13:49 《快乐王子》实为《快乐王子集》&#xff0c;另两篇为《自私的巨人》和《年轻的国王》。作者王尔德为世界著名一流童话作家&#xff0c;深谙童话奥妙。这本童话集举世闻名&#xff0c;脍炙人口&#xff0c;被文学界推崇为童话经典. 原文快乐王子的雕像高高地耸立在城市…

小王子 中英读物

小王子 第一章 —we are introduced to the narrator, a pilot, and his ideas about grown-ups ——我们将认识这位叙述者&#xff0c;一位飞行员&#xff0c;并了解他对成年人的看法 Once when I was six years old I saw a magnificent picture in a book, called True S…

小王子

http://user.qzone.qq.com/171452508/blog/1213165142 http://user.qzone.qq.com/171452508/blog/1213166518 http://user.qzone.qq.com/171452508/blog/1213166645 http://user.qzone.qq.com/171452508/blog/1213166677

法国童话故事《小王子》读后感

本来这篇文章想自己写写的。 可是怕被某人骂语言白痴... 当然这不是主要原因.. 所以索性决定转帖别人的。 反正被骂也不是我写的..嘿嘿.. 不过很可笑的是&#xff0c;虽然是儿童读物&#xff0c;有人却必须要写成论文。以大人的眼光看待整个问题。 想想这的确是与原著相悖&…

王子回家-第12届蓝桥杯Scratch省赛2真题第3题

[导读]&#xff1a;超平老师计划推出Scratch蓝桥杯真题解析100讲&#xff0c;这是超平老师解读Scratch蓝桥真题系列的第48讲。 第12届蓝桥杯青少年组省赛分两次进行&#xff0c;这是2020年10月19日举行的第一次省赛考试中级组&#xff0c;形式为在线考试。Scratch分为初级组和…

《小王子》精彩章节——Chapter 21

《小王子》精彩章节——Chapter 21 说明&#xff1a; 金色字体是文中细节性的描述&#xff0c;红色加粗字体是值得品读的句子方框内对应的是上边红色加粗字体&#xff0c;是个人的浅薄认知另外&#xff0c;本文也附加了李继宏在导读中的点评欢迎在评论区交流指正 就在这时&…

蓝桥杯小王子问题

题目描述 小王子有一天迷上了排队的游戏&#xff0c;桌子上有标号为 1-101−10 的 1010 个玩具&#xff0c;现在小王子将他们排成一列&#xff0c;可小王子还是太小了&#xff0c;他不确定他到底想把那个玩具摆在哪里&#xff0c;直到最后才能排成一条直线&#xff0c;求玩具的…

王子与骑士-第14届蓝桥杯STEMA测评Scratch真题精选

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第101讲。 蓝桥杯选拔赛现已更名为STEMA&#xff0c;即STEM 能力测试&#xff0c;是蓝桥杯大赛组委会与美国普林斯顿多…