【蓝桥杯】十四招式冲刺之 “第一招”《链表》

前言

-🏀大家好,我是BXuan,热爱编程与篮球的软件工程大二学生一名
-📚近期在准备4月份的蓝桥省赛,本章与大家一起聊聊有关链表的问题!如文有误,请大家指出并多多包涵。
-🏃‍放弃不难,但坚持一定很酷。


🚩概念

①链表是线性表的链式存取的数据结构,是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

②链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:数据域(数据元素的映象)+ 指针域(指示后继元素存储位置),数据域就是存储数据的存储单元,指针域就是连接每个结点的地址数据。

🚩顺序存储VS链式存储

  • 顺序存储
    在这里插入图片描述

  • 链式存储
    在这里插入图片描述

🚩顺序表VS链表

顺序表

优点:

  1. 无需为表示结点间的逻辑关系而增加额外的存储空间(因为逻辑上相邻的元素其存储的物理位置也是相邻的);
    图片描述

  2. 可方便地随机存取表中的任一元素:由于顺序表每个元素的大小相等,且知道第几个元素就可以通过计算得到任意元素的地址,既可以随机存取任一元素。

缺点:

  1. 插入或删除运算不方便:除表尾的位置外,在表的其它位置上进行插入或删除操作都必须移动大量的结点,其效率较低;
    如在 7、8 之 间插入 X 元素,那我们为了保证其顺序性需要把 8 和 9 向后移动一位,再将 X 放到 8 的位置。
    在这里插入图片描述

    这样的存储方式增加了处理器和 IO 资源的消耗代价,这是我们不愿意看到的,至于删除其原理相同。

  2. 难以匹配存储规模:
    由于顺序表要求占用连续的存储空间,存储分配只能预先进行静态分配,因此当表长变化较大时,难以确定合适的存储规模。

时间复杂度

查找操作为 O(1),插入和删除操作为 O(n)。

链表

优点:

  1. 插入和删除速度快,保留原有的物理顺序,在插入或者删除一个元素的时候,只需要改变指针指向即可;
  2. 没有空间限制, 存储元素无上限, 只与内存空间大小有关;
  3. 动态分配内存空间,不用事先开辟内存;
  4. 使内存的利用率变高。

缺点:

  1. 占用额外的空间以存储指针,比较浪费空间,不连续存储,Malloc 函数开辟空间碎片比较多;
  2. 查找速度比较慢,因为在查找时,需要循环遍历链表。

时间复杂度:

查找操作为 O(n), 插入和删除操作为 O(1)。

🚩知识点

  • 单链表实现原理与应用
  • 循环链表实现原理与应用
  • 双向链表实现原理与应用

一、小王子(单链表)

问题描述

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

要求一:采用单链表解决

输入描述

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

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

输出描述

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

运行限制

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

输入输出案例

输入
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

代码示例

import java.util.Scanner;
//1:无需package
//2: 类名必须Main, 不可修改

public class Main {
   
// 构建单链表结构
static class Node{
   
 int data; // 数据域
 Node next; // 指针域
 // 传入当前链表的数据域的值
 Node(int v){
   
   data = v;
 }
}
// 将头节点单独插入到链表中
static Node head = new Node(1);
// 构建插入函数
static void init(){
   
 // 首先将
 Node x = head;
 for(int i = 1;i <= 10;i++){
   
   x=(x.next = new Node(i));
 }
 x.next = null;
}
//然后选中的数字 就在链表中将其删除,然后重新插入到头节点后面
static void del(int x){
   
 Node before = head;
 for(Node T = head.next;T != null;T = T.next){
   
   if(T.data == x){
   
     //在删除之前需要将临时结点保存然后方便后续进行插入
     Node temp = T;
     before.next = T.next;
     //结束函数
     return;
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BXuan随笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值