线性表、单循环链表学习

news2025/1/22 12:16:48

背景:
在这里插入图片描述

单循环链表是一种链表结构,其中最后一个节点指向第一个节点,从而形成一个环。

实现单循环链表通常涉及节点定义、插入节点、删除节点以及遍历链表等操作。以下是如何在Python中实现单循环链表的示例。

单循环链表的实现

1. 节点类

首先,定义链表的节点类,每个节点包含数据和指向下一个节点的指针。

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
2. 单循环链表类

接下来,定义单循环链表类,包含插入、删除和遍历等方法。

class CircularLinkedList:
    def __init__(self):
        self.head = None

    def insert(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            self.head.next = self.head
        else:
            current = self.head
            while current.next != self.head:
                current = current.next
            current.next = new_node
            new_node.next = self.head

    def delete(self, key):
        if self.head is None:
            return
        
        current = self.head
        prev = None

        while True:
            if current.data == key:
                if prev:
                    prev.next = current.next
                else:
                    # Deleting the head node
                    if current.next == self.head:
                        self.head = None
                    else:
                        tail = self.head
                        while tail.next != self.head:
                            tail = tail.next
                        tail.next = current.next
                        self.head = current.next
                return
            
            prev = current
            current = current.next

            if current == self.head:
                break

    def display(self):
        if self.head is None:
            print("List is empty")
            return
        
        current = self.head
        while True:
            print(current.data, end=" -> ")
            current = current.next
            if current == self.head:
                break
        print()

# 示例使用
cll = CircularLinkedList()
cll.insert(1)
cll.insert(2)
cll.insert(3)
cll.display()  # 输出: 1 -> 2 -> 3 -> 

cll.delete(2)
cll.display()  # 输出: 1 -> 3 -> 

代码解释

  1. 节点类 (Node):

    • __init__: 初始化节点的数据和指向下一个节点的指针。
  2. 单循环链表类 (CircularLinkedList):

    • __init__: 初始化链表的头指针。
    • insert: 在链表中插入新节点。
      • 如果链表为空,插入第一个节点并使其指向自己。
      • 如果链表不为空,找到最后一个节点并将其next指针指向新节点,然后将新节点的next指针指向头节点。
    • delete: 删除包含指定数据的节点。
      • 如果链表为空,直接返回。
      • 找到要删除的节点并更新前一个节点的next指针。
      • 如果删除的是头节点,处理特殊情况,找到尾节点并更新其next指针指向新的头节点。
    • display: 遍历并打印链表中的所有节点。

总结

单循环链表是一种方便的数据结构,适用于需要循环访问数据的场景。上面的代码展示了如何在Python中实现单循环链表的基本操作,包括插入、删除和遍历。

线性表和单链表都是常见的数据结构,用于存储和管理数据元素。它们有各自的特点和应用场景。下面详细介绍它们的概念、特点、优缺点,以及适用的场景。

线性表

概念

线性表(Linear List)是具有相同数据类型的 n 个元素的有限序列。在逻辑结构上,线性表中的数据元素具有线性关系,即每个元素有且只有一个前驱和一个后继(除第一个和最后一个元素外)。

特点
  • 有序性:线性表中的元素按线性顺序排列。
  • 唯一的前驱和后继:每个元素除了第一个元素没有前驱和最后一个元素没有后继外,其余元素都有唯一的前驱和后继。
  • 长度可变:线性表的长度是可变的,可以动态增删元素。
实现方式
  1. 顺序存储结构(数组)
  2. 链式存储结构(链表)

单链表

概念

单链表(Singly Linked List)是一种链式存储结构,其中每个节点包含数据域和指向下一个节点的指针。链表中的最后一个节点的指针指向空(None),表示链表的结束。

特点
  • 动态存储:不需要预先分配存储空间,可以动态地进行内存分配。
  • 插入和删除操作高效:在已知位置进行插入和删除操作时,无需移动其他元素,只需改变指针指向。
  • 顺序访问:只能从头节点开始顺序访问各节点,无法直接随机访问。
结构
  • 节点:包含数据域(存储数据)和指针域(指向下一个节点)。
  • 头指针:指向链表的第一个节点。

比较与对比

共同点
  • 线性结构:线性表和单链表都属于线性结构,元素之间具有线性关系。
  • 基本操作:都支持插入、删除、查找、更新、遍历等基本操作。
不同点
特点线性表(顺序存储)单链表
存储方式数组链表
内存分配需预先分配连续空间动态分配
随机访问支持不支持
插入和删除效率低,需移动元素高,只需修改指针
空间利用率可能存在空间浪费高效
实现难度简单较复杂
适用场景
  • 线性表(数组)

    • 适用于元素数量固定且变化不大的场景。
    • 适用于需要频繁随机访问元素的场景。
    • 适用于存储大小一致的数据(如基本数据类型)。
  • 单链表

    • 适用于元素数量变化频繁的场景。
    • 适用于插入和删除操作较多的场景。
    • 适用于数据量较大且不确定的场景。

示例代码

顺序存储(数组实现)
class LinearList:
    def __init__(self):
        self.data = []

    def insert(self, index, element):
        if index < 0 or index > len(self.data):
            raise IndexError("Index out of bounds")
        self.data.insert(index, element)

    def delete(self, index):
        if index < 0 or index >= len(self.data):
            raise IndexError("Index out of bounds")
        return self.data.pop(index)

    def get(self, index):
        if index < 0 or index >= len(self.data):
            raise IndexError("Index out of bounds")
        return self.data[index]

    def update(self, index, element):
        if index < 0 or index >= len(self.data):
            raise IndexError("Index out of bounds")
        self.data[index] = element

    def length(self):
        return len(self.data)

    def display(self):
        print(self.data)

# 示例使用
linear_list = LinearList()
linear_list.insert(0, 1)
linear_list.insert(1, 2)
linear_list.insert(2, 3)
linear_list.display()  # 输出: [1, 2, 3]

linear_list.update(1, 5)
linear_list.display()  # 输出: [1, 5, 3]

linear_list.delete(2)
linear_list.display()  # 输出: [1, 5]

print(linear_list.get(1))  # 输出: 5
print(linear_list.length())  # 输出: 2
单链表实现
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None

    def insert(self, index, element):
        new_node = Node(element)
        if index == 0:
            new_node.next = self.head
            self.head = new_node
            return

        current = self.head
        for _ in range(index - 1):
            if current is None:
                raise IndexError("Index out of bounds")
            current = current.next
        
        new_node.next = current.next
        current.next = new_node

    def delete(self, index):
        if self.head is None:
            raise IndexError("Index out of bounds")

        if index == 0:
            self.head = self.head.next
            return

        current = self.head
        for _ in range(index - 1):
            if current.next is None:
                raise IndexError("Index out of bounds")
            current = current.next
        
        if current.next is None:
            raise IndexError("Index out of bounds")
        
        current.next = current.next.next

    def get(self, index):
        current = self.head
        for _ in range(index):
            if current is None:
                raise IndexError("Index out of bounds")
            current = current.next
        
        if current is None:
            raise IndexError("Index out of bounds")
        
        return current.data

    def update(self, index, element):
        current = self.head
        for _ in range(index):
            if current is None:
                raise IndexError("Index out of bounds")
            current = current.next
        
        if current is None:
            raise IndexError("Index out of bounds")
        
        current.data = element

    def length(self):
        count = 0
        current = self.head
        while current:
            count += 1
            current = current.next
        return count

    def display(self):
        current = self.head
        while current:
            print(current.data, end=" -> ")
            current = current.next
        print("None")

# 示例使用
linked_list = LinkedList()
linked_list.insert(0, 1)
linked_list.insert(1, 2)
linked_list.insert(2, 3)
linked_list.display()  # 输出: 1 -> 2 -> 3 -> None

linked_list.update(1, 5)
linked_list.display()  # 输出: 1 -> 5 -> 3 -> None

linked_list.delete(2)
linked_list.display()  # 输出: 1 -> 5 -> None

print(linked_list.get(1))  # 输出: 5
print(linked_list.length())  # 输出: 2

总结

线性表和单链表各有优缺点和适用场景。选择使用哪种数据结构,取决于具体的应用需求和操作频率。在需要频繁随机访问数据的场景下,线性表(数组)更为合适;在需要频繁插入和删除操作的场景下,单链表则更为高效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1789699.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

组合和为N的数量-第13届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第78讲。 组合和为N的数量&…

低代码选型要注意什么问题?

低代码选型时&#xff0c;确实需要从多个角度综合考虑&#xff0c;以下是根据您给出的角度进行的分析和建议&#xff1a; 公司的人才资源&#xff1a; 评估团队中是否有具备编程能力的开发人员&#xff0c;以确保能够充分利用低代码平台的高级功能和进行必要的定制开发。考察实…

Transformer系列:图文详解KV-Cache,解码器推理加速优化

前言 KV-Cache是一种加速Transformer推理的策略&#xff0c;几乎所有自回归模型都内置了KV-Cache&#xff0c;理解KV-Cache有助于更深刻地认识Transformer中注意力机制的工作方式。 自回归推理过程知识准备 自回归模型采用shift-right的训练方式&#xff0c;用前文预测下一个…

tinyrenderer-切线空间法线贴图

法线贴图 法线贴图分两种&#xff0c;一种是模型空间中的&#xff0c;一种是切线空间中的 模型空间中的法线贴图的rgb代表着每个渲染像素法线的xyz&#xff0c;与顶点坐标处于一个空间&#xff0c;图片是五颜六色的。 切线空间中的法线贴图的rgb同样对应xyz&#xff0c;是切线…

Django里多app

在 Django 里的某一个项目&#xff0c;里面得包含很多 App (功能)&#xff0c;那么如何在该项目里管理这么多App呢&#xff1f; 先说明下背景&#xff1a;未先创建 apps 文件夹来存各个app文件夹&#xff0c;直接在项目文件目录里创建各个app。为了便于管理&#xff0c;得将各…

YOLOv10(2):网络结构及其检测模型代码部分阅读

YOLOv10&#xff08;1&#xff09;&#xff1a;初探&#xff0c;训练自己的数据-CSDN博客 目录 1. 写在前面 2. 局部模块 &#xff08;1&#xff09;SCDown &#xff08;2&#xff09;C2fCIB &#xff08;3&#xff09;PSA(partial self-attention) 3. 代码解读 &#x…

【简单学习一下卷积神经网络】-基于肆十二的高考例子

前言一、白话卷积神经网络总结 前言 【参考】 主要是P2⇨手把手教你用tensorflow2训练自己的数据集 -------2024/5/4 一、白话卷积神经网络 高考前需要大量的做题训练---->相当于数据集。 做题过程中【于标准答案进行比对】产生的错题⇨loss&#xff08;误差&#xff09; 回…

数据新生态:Web3如何重新定义个人数据权利

随着数字化时代的不断深入&#xff0c;个人数据已经成为了现代社会中最宝贵的资源之一。然而&#xff0c;传统互联网时代下&#xff0c;个人数据往往被大型科技公司垄断、滥用&#xff0c;个人数据权利常常受到侵犯。而随着Web3技术的崛起&#xff0c;人们开始期待一种全新的数…

R_AARCH64_ADR_PREL_PG_HI21问题说明

目录 问题现象&#xff1a; 问题原因 问题机理 问题现象&#xff1a; 客户现场加载out文件出现如下问题&#xff1a; 打印“Relocation of type ‘R_AARCH64_ADR_PREL_PG_HI22…..’”,明确是ARDP指令引起的问题 问题原因 ARDP的寻址范围是4GB范围&#xff0c;加载的位置…

【用Python画画】六一儿童节画爱心

本文收录于 《Python编程入门》专栏&#xff0c;从零基础开始&#xff0c;分享一些Python编程基础知识&#xff0c;欢迎关注&#xff0c;谢谢&#xff01; 文章目录 一、前言二、代码示例三、知识点梳理四、总结 一、前言 本文介绍如何使用Python的海龟画图工具turtle&#xf…

取代Windows的系统复制粘贴等文件处理

TeraCopy 可以到官网下载也可以通过应用商店下载 主要作用 : 取代Windows的系统复制粘贴等文件处理 常规窗口 点击第一排最左侧的按钮会显示这个窗口, 显示所以文件操作记录 , 这个也是我装这个软件的原因之一, 框选的是当前正在进行的 当执行复制粘贴时会自动出现, 让自行…

html three.js 引入.stl模型示例

1.新建一个模块用于放置模型 <div id"chart_map" style"width:800px;height:500px"></div> 2. 引入代码根据需求更改 <!-- 在head或body标签内加入以下链接 --> <script src"https://cdn.jsdelivr.net/npm/three0.137/build/t…

基于R语言BIOMOD2 及机器学习方法的物种分布模拟

BIOMOD2是一个R软件包&#xff0c;用于构建和评估物种分布模型&#xff08;SDMs&#xff09;。它集成了多种统计和机器学习方法&#xff0c;如GLM、GAM、SVM等&#xff0c;允许用户预测和分析物种在不同环境条件下的地理分布。通过这种方式&#xff0c;BIOMOD帮助研究者评估气候…

零刻SER8 AMD 8845Hs Ryzen AI 本地部署大语言模型教程!

零刻SER8 8845HS,配备了一个内置的 NPU&#xff08;神经网络处理单元&#xff09;&#xff0c;可以通过LM Studio语言大模型来部署己的 GPT 模型 AI 聊天机器人&#xff0c;AI 助手已迅速成为提高生产力、效率&#xff0c;甚至是头脑风暴的关键资源。在本地机器上运行 AI 聊天机…

前端列表可滚动,可轮播

前端列表可滚动&#xff0c;可轮播 <ulclass"scroll-list"ref"scroll_List"mouseenter"cancelScroll()"mouseleave"autoScroll()"><liclass"list-item"v-for"(item,index) in tableData3":class"[…

java现饱和,有必要去学其他语言吗?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「 java的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;如果有时间总比不学好&…

虹科免拆诊断案例 | 2013 款路虎神行者 2 车偶发性无法起动

故障现象 一辆2013款路虎神行者2车&#xff0c;搭载2.0 L Si4 Petrol发动机&#xff0c;累计行驶里程约为4.5万km。车主反映&#xff0c;车辆偶发性无法起动&#xff0c;故障出现时&#xff0c;尝试起动发动机&#xff0c;组合仪表上会出现“挡位不在驻车挡”“充电系统故障”…

【Qt】 new成功,但是没有进入到构造函数。

NameTest工程中 nametest.cpp NameTest::NameTest() {pdata new privateAB; }NameTest::~NameTest() {if (pdata){privateAB *p (privateAB *)pData; //void *pdata nullptr;delete p;pdata nullptr;} }内部类&#xff1a; privateAB #include "private.h"#i…

密码学基本概念(补充)

BiBa模型的*特性规则&#xff1a;主体不能修改更高完整级的客体&#xff08;主题不能向上写&#xff09; Diffie-Hellman密钥交换协议的安全性基于求解离散对数的困难性&#xff0c;既对于C^d M mod P&#xff0c;在已知C和P的前提下&#xff0c;由d求M很容易&#xff0c;但是…

使用Nginx正向代理让内网主机通过外网主机访问互联网

目录 环境概述 流程说明 在外网服务器上安装部署nginx 安装前准备 下载nginx 编译安装nginx 开始配置正向代理 创建systemd服务单元文件&#xff0c;用于管理Nginx服务的启动、停止和重新加载 启动nginx 代理服务器本地验证 内网服务器验证 将代理地址添加到环境变量中…