Python单向循环链表操作

news2024/10/5 21:22:30

目录

一、单向循环链表

单向循环链表图

 二、单向循环链表的操作

1、判断链表是否为空

2,链表长度

3,遍历整个链表

4,在链表头部添加元素

5、链表尾部添加元素

6,在指定位置插入元素

7,修改指定位置的元素

8,删除元素

9、查找元素是否存在

三、完整代码


一、单向循环链表

单向循环链表图

结点node里有两个部分:elem(元素)和next(指向下一结点的指针),head指针指向头结点,并且尾结点next又指向头结点

 二、单向循环链表的操作

1、判断链表是否为空

    def is_empty(self):
        # 链表是否为空
        if self.__head is None:
            return True
        else:
            return False


2,链表长度

    def length(self):
        # 链表长度
        if self.is_empty():
            return 0
        count = 0
        cur = self.__head
        while cur.next != self.__head:
            count += 1
            cur = cur.next
        return count


3,遍历整个链表

    def travel(self):
     # 遍历整个链表
        if self.is_empty():
            return
        cur = self.__head
        while cur.next != self.__head:
            print(cur.elem, end=' ')
            cur = cur.next
        print(cur.elem)


4,在链表头部添加元素

    def add(self, item):
        # 链表头部添加元素
        node = Node(item)
        if self.is_empty():
            self.__head = node
            node.next = node
        else:
            tail = self.__head
            # 循环找到尾结点
            while tail.next != self.__head:
                tail = tail.next
            # 新来的节点的next指向第一个节点
            node.next = self.__head
            # 再改变第一个节点的指针指向新节点
            self.__head = node
            # 最后将尾指向指向添加node节点
            tail.next = node


5、链表尾部添加元素

    def append(self, item):
        # 链表尾部添加元素
        # 创建新结点
        node = Node(item)
        # 是空链表就把头节点指向这个节点
        if self.is_empty():
            self.__head = node
            node.next = node
        else:
            tail = self.__head
            # 找到尾节点
            while tail.next != self.__head:
                tail = tail.next
            tail.next = node
            node.next = self.__head


6,在指定位置插入元素


遍历让指针指向要插入的位置,修改前后指针的指向

    def insert(self, pos, item):
        # 位置pos在第一个元素之前,则在头部插入
        if pos <= 0:
            self.add(item)
            # 位置pos大于总长度,则在尾部插入
        elif pos > self.length():
            self.append(item)
        else:
            # 指定位置添加元素
            node = Node(item)
            count = 0
            pre = self.__head
            # 循环定位指针位置
            while count < (pos-1):
                count += 1
                pre = pre.next
            node.next = pre.next
            pre.next = node

7,修改指定位置的元素
 

    def modify(self, pos, item):
        """修改指定位置的元素"""
        # 当指定的位置pos小于等于0时,则修改头部元素
        if pos <= 0:
            self.__head.elem = item
        # 当pos大于等于链表总长度时,则修改尾部元素
        elif pos >= self.length():
            tail = self.__head
            # 循环让指针指向尾部元素
            while tail.next != self.__head:
                tail = tail.next
            tail.elem = item  # 修改尾部元素
        else:
            count = 0
            tail = self.__head
            # 循环指针找到指定的位置
            while count < pos:  # 1.当不满足条件退出循环时,说明指针已经指向了给定的pos位置
                tail = tail.next
                count += 1
            tail.elem = item  # 2.将pos位置的元素修改

8,删除元素
 

    def remove(self, item):
        # 删除节点
        cur = self.__head  # cur当前指针
        pre = None  # 前一个指针
        while cur.next != self.__head:
            # 找到了要删除的元素
            if cur.elem == item:
                # 要删除的元素就是第一个元素
                if cur == self.__head:
                    tail = self.__head
                    # 让tail指向最后一个元素
                    while tail.next != self.__head:
                        tail = tail.next
                    # 删除第一个节点,改变指针的指向
                    tail.next = cur.next
                    self.__head = cur.next
                else:
                    pre.next = cur.next
                return
            # 未找到要删除的元素,指针向后走,继续遍历
            else:
                pre = cur
                cur = cur.next
        # 当上面的while循环不满足条件时(cur.next == self.__head),说明只有一个结点元素
        if cur.elem == item:
            if cur.next == self.__head:
                pre.next = self.__head

9、查找元素是否存在
 

    def search(self, item):
        # 查找节点是否存在
        cur = self.__head
        while cur.next != self.__head:
            # 找到了返回True,未回到指向下一个继续遍历
            if cur.elem == item:
                return True
            cur = cur.next
        # 查找的元素在最后一个,遍历后指向最后一个,但是没有进入循环,所以需要在循环体外判断一次
        if cur.elem == item:
            return True
        return False

三、完整代码

class Node():
    def __init__(self, elem):
        # 单链表结点
        self.elem = elem
        self.next = None


class SingleCircleLinkList():
    def __init__(self, node=None):
        self.__head = node
        if node:
            node.next = node  # 只有一个结点时,next指针指向自己,构成循环

    def is_empty(self):
        # 链表是否为空
        if self.__head is None:
            return True
        else:
            return False

    def length(self):
        # 链表长度
        if self.is_empty():
            return 0
        count = 0
        cur = self.__head
        while cur.next != self.__head:
            count += 1
            cur = cur.next
        return count

    def travel(self):
     # 遍历整个链表
        if self.is_empty():
            return
        cur = self.__head
        while cur.next != self.__head:
            print(cur.elem, end=' ')
            cur = cur.next
        print(cur.elem)

    def add(self, item):
        # 链表头部添加元素
        node = Node(item)
        if self.is_empty():
            self.__head = node
            node.next = node
        else:
            tail = self.__head
            # 循环找到尾结点
            while tail.next != self.__head:
                tail = tail.next
            # 新来的节点的next指向第一个节点
            node.next = self.__head
            # 再改变第一个节点的指针指向新节点
            self.__head = node
            # 最后将尾指向指向添加node节点
            tail.next = node

    def append(self, item):
        # 链表尾部添加元素
        # 创建新结点
        node = Node(item)
        # 是空链表就把头节点指向这个节点
        if self.is_empty():
            self.__head = node
            node.next = node
        else:
            tail = self.__head
            # 找到尾节点
            while tail.next != self.__head:
                tail = tail.next
            tail.next = node
            node.next = self.__head

    def modify(self, pos, item):
        """修改指定位置的元素"""
        # 当指定的位置pos小于等于0时,则修改头部元素
        if pos <= 0:
            self.__head.elem = item
        # 当pos大于等于链表总长度时,则修改尾部元素
        elif pos >= self.length():
            tail = self.__head
            # 循环让指针指向尾部元素
            while tail.next != self.__head:
                tail = tail.next
            tail.elem = item  # 修改尾部元素
        else:
            count = 0
            tail = self.__head
            # 循环指针找到指定的位置
            while count < pos:  # 1.当不满足条件退出循环时,说明指针已经指向了给定的pos位置
                tail = tail.next
                count += 1
            tail.elem = item  # 2.将pos位置的元素修改

    def insert(self, pos, item):
        # 位置pos在第一个元素之前,则在头部插入
        if pos <= 0:
            self.add(item)
            # 位置pos大于总长度,则在尾部插入
        elif pos > self.length():
            self.append(item)
        else:
            # 指定位置添加元素
            node = Node(item)
            count = 0
            pre = self.__head
            # 循环定位指针位置
            while count < (pos-1):
                count += 1
                pre = pre.next
            node.next = pre.next
            pre.next = node

    def remove(self, item):
        # 删除节点
        cur = self.__head  # cur当前指针
        pre = None  # 前一个指针
        while cur.next != self.__head:
            # 找到了要删除的元素
            if cur.elem == item:
                # 要删除的元素就是第一个元素
                if cur == self.__head:
                    tail = self.__head
                    # 让tail指向最后一个元素
                    while tail.next != self.__head:
                        tail = tail.next
                    # 删除第一个节点,改变指针的指向
                    tail.next = cur.next
                    self.__head = cur.next
                else:
                    pre.next = cur.next
                return
            # 未找到要删除的元素,指针向后走,继续遍历
            else:
                pre = cur
                cur = cur.next
        # 当上面的while循环不满足条件时(cur.next == self.__head),说明只有一个结点元素
        if cur.elem == item:
            if cur.next == self.__head:
                pre.next = self.__head

    def search(self, item):
        # 查找节点是否存在
        cur = self.__head
        while cur.next != self.__head:
            # 找到了返回True,未回到指向下一个继续遍历
            if cur.elem == item:
                return True
            cur = cur.next
        # 查找的元素在最后一个,遍历后指向最后一个,但是没有进入循环,所以需要在循环体外判断一次
        if cur.elem == item:
            return True
        return False


if __name__ == '__main__':
    ll = SingleCircleLinkList()
    print(ll.is_empty())
    print(ll.length())
    ll.travel()

    print('add')
    ll.add(9)
    ll.travel()
    ll.add(10)
    ll.travel()

    print('append')
    ll.append(13)
    ll.travel()

    print('insert')
    ll.insert(5, 33)
    ll.travel()

    print('remove')
    ll.travel()
    ll.remove(10)
    ll.travel()

    print('modify')
    ll.modify(2, 100)
    ll.travel()

    print(ll.search(33))

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

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

相关文章

JavaSE 和 Java EE 分别是什么

Java 作为最流行的编程语言受到了许多人的喜爱&#xff0c;其在编程中的地位自不必多说。 对于许多才刚刚入门 Java 的朋友来讲&#xff0c;常常会产生这样的困惑&#xff0c;JavaEE是什么&#xff1f;JavaSE又是什么&#xff1f; Java SE Java SE 是 Java Platform, Standa…

Liunx下进程间通信

文章目录 前言1.进程间通信相关介绍2.管道1.匿名管道2.管道的原理3.通过代码来演示匿名管道4.命名管道5.命名管道的原理6.命名管道代码演示 3.System V共享内存1.共享内存原理2.相关系统接口的介绍与共享内存的代码演示3.共享内存的一些特性 4.system V消息队列与system V信号量…

依赖注入方式

Spring中有哪些注入方式? 我们先来思考 向一个类中传递数据的方式有几种? 普通方法(set方法)构造方法 依赖注入描述了在容器中建立bean与bean之间的依赖关系的过程&#xff0c;如果bean运行需要的是数字或 字符串呢? 引用类型简单类型(基本数据类型与String) Spring就…

Primo Ramdisk内存盘工具软件

简介 Primo Ramdisk 软件的主要功能是通过独特的软件算法将物理内存模拟成一个超快速的硬盘&#xff0c;在这个虚拟硬盘上的读写操作均在内存中完成。由于物理内存的访问速度远远超过物理硬盘&#xff0c;因此虚拟硬盘具有非常高的数据读写速度&#xff0c;从而突破系统IO瓶颈&…

“SCSA-T学习导图+”系列:下一代防火墙

本期引言&#xff1a; 近年来&#xff0c;随着数字化业务带给我们高效和便捷的同时&#xff0c;信息暴露面的增加、网络边界的模糊化以及黑客攻击的产业化&#xff0c;使得网络安全事件相较以往成指数级增加。传统防火墙基于五元组的方式对进出网络的数据流量进行访问控制&…

医院影像图像科室工作站PACS系统 DICOM 三维图像后处理与重建

PACS报告系统的主要任务是通过运用不断积累诊断常用语&#xff0c;减轻出报告的劳动强度&#xff0c;并且将报告保存成电子文档以便日后查阅。在PACS的报告系统中&#xff0c;有三种不同层次的方法输入文字—“高级模板”、“分类词条”和“短语词典”。这三种方法的内容都可以…

记一次从JS到内网的横向案例

前言 前段时间参加了一场攻防演练&#xff0c;使用常规漏洞尝试未果后&#xff0c;想到不少师傅分享过从JS中寻找突破的文章&#xff0c;于是硬着头皮刚起了JS&#xff0c;最终打开了内网入口获取了靶标权限和个人信息。在此分享一下过程。 声明&#xff1a;本次演练中&#xf…

C/C++每日一练(20230422)

目录 1. 存在重复元素 &#x1f31f; 2. 组合总和 &#x1f31f;&#x1f31f; 3. 给表达式添加运算符 &#x1f31f;&#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日…

java基于J2EE的学生宿舍信息管理系统

本目 录 摘 要 I ABSTRACT II 第一章 绪论 1 1.1课题研究背景 1 1.2课题的目的和意义 1 1.3开发工具及简介 2 1.3.1开发工具 2 1.3.2 JSP技术 3 1.3.3 JavaScript 4 第二章 需求分析 4 2.1可行性分析 4 2.1.1技术的可行性 4 2.1.2经济的…

Faster RCNN系列1——Anchor生成过程

Faster RCNN系列&#xff1a; Faster RCNN系列1——Anchor生成过程 Faster RCNN系列2——RPN的真值与预测值概述 Faster RCNN系列3——RPN的真值详解与损失值计算 Faster RCNN系列4——生成Proposal与RoI Faster RCNN系列5——RoI Pooling与全连接层 一、RPN模块概述 RPN模块…

jsp946+java物流信息管理平台-sqlserver

本系统是一个独立的系统&#xff0c;用来解决物流信息信息的管理问题。采用JSP技术构建了一个有效而且实用的物流信息信息管理平台&#xff0c;目的是为高效地完成对物流信息信息的管理。 1、内部办公功能&#xff1a;包含工作计划、通告管理、公文管理&#xff1b; 包括可以…

手机录音误删怎么恢复?恢复录音,就这么简单!

案例&#xff1a;手机录音删除了还能恢复吗&#xff1f; 【友友们&#xff0c;苹果手机录音删除了还可以恢复吗&#xff1f;里面有一些关于会议记录的录音&#xff0c;不小心被我删了&#xff0c;有哪些方法可以快速恢复录音文件&#xff1f;】 如果您在使用iPhone手机录音时误…

Python小姿势 - ### Python之禅

Python之禅 Python之禅&#xff08;The Zen of Python&#xff09;是Python之父Guido van Rossum所著的一篇文章&#xff0c;总结了Python语言的哲学。 文章开头写道&#xff1a; Beautiful is better than ugly. Explicit is better than implicit. Simple is better than com…

代码随想录--字符串--反转字符串题型

反转字符串 不能给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 我们直接用双指针&#xff0c;一个指头一个指尾&#xff0c;swap交换&#xff0c;然后同时往中间走一步再进入循环交换即可。 反转字符串II 这道题我们容…

linux(18.04)编译安装python3.6的全过程,pip python不与linux系统环境混乱

因为使用要求&#xff0c;使得我需要在linux环境下安装一个独立的python环境&#xff0c;不干扰其他环境。 一&#xff0c;下载python资源包 两种下载方式二选一&#xff0c;谁快选谁 linux下载&#xff1a; 不同的python版本&#xff0c;安装过程是一样的&#xff0c;下载…

蒙层禁止页面滚动

学习链接&#xff1a;蒙层禁止页面滚动的方案 <!DOCTYPE html> <html> <head><meta charset"utf-8"><meta name"viewport" content"widthdevice-width, initial-scale1"><title>蒙层禁止页面滚动的方案<…

Map Reduce高级篇:Join-Reduce

Join关联操作 背景 在实际的数据库应用中&#xff0c;我们经常需要从多个数据表中读取数据&#xff0c;这时就可以使用SQL语句中的连接&#xff08;JOIN&#xff09;&#xff0c;在两个或者多个数据表中查询数据。在使用MapReduce框架进行数据查询的过程中&#xff0c;也会涉…

React Refs

React 支持一种非常特殊的属性 Ref &#xff0c;可以用来绑定到 render() 输出的任何组件上。 这个特殊的属性允许引用 render() 返回的相应的支撑实例 &#xff08; backing instance &#xff09;。这样就可以确保在任何时间总是拿到正确的实例。 使用&#xff1a; 绑定一…

Linux基础—DHCP原理与配置

Linux基础—DHCP原理与配置 一、DHCP工作原理1.了解DHCP服务使用DHCP的优势DHCP的分配方式 2.DHCP的IP地白动获取工作原理: 二、配置DHCP服务器三、DHCP场景应用实验 一、DHCP工作原理 1.了解DHCP服务 DHCP(Dynamic HostConfiguration Protocol&#xff0c;动态主机配置协议) …

网络基础入门

目录 网络存在的意义 网络发展 网络在哪里&#xff1f; 网络是分层的 理解分层 软件可以分层 网络协议栈也是层状结构 认识协议 协议是什么 协议分层 网络传输需要解决的四个问题 OSI七层模型&#xff08;了解为主&#xff09; TCP/IP五层&#xff08;或四层&…