热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

单向双向链表的实现

用面向对象实现LinkedList链表单向链表实现append、iternodes方法双向链表实现append、pop、insert、remove、iternodes方法链表的好处

用面向对象实现LinkedList链表

单向链表实现append、iternodes方法

双向链表实现append、pop、insert、remove、iternodes方法

链表的好处:

            查询慢、插入追加删除快

思路:

# 单向链表 1 2 2 3 3 4 4 5 5 6 None 最基本的链表结构

# 链表由 每一个数据块组成 串联在一起就是链表

#先定义数据块 Node

class Node1:  ##(item -> next)

    def __init__(self,item, next=None):

        self.item = item

        self.next = next

    def __repr__(self):

        return '<{}--->{}>'.format(self.item,

                                      self.next.item if self.next else 'None') #???怎么理解这句话 

#构造单向链表

class Singelinked:

    def __init__(self): #设定开头和结尾 这是一个链表最基本的属性 初始链表的开头和结尾为None

        self.head = None

        self.tail = None

    def append(self,item):

        Node = Node1(item)  ##构造一个要添加的节点 然后写入到链表中

        if self.head is None:  #

            self.head = Node ##如果是空的直接追加

            self.tail = Node     

        else:

            self.tail.next = Node #不为空 就在最后一个尾部 追加 然后追加完成后 把前一个的next 变成 node

            self.tail = Node

        return self

    def iterlink(self):

        current = self.head   #当前的头部

        while current:      #无限循环 知道 当前为None 等效False

            yield current

            current = current.next  

双向链表的结构: 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

##先定义数据块 Node

class Node2:  ##(item -> next)

    def __init__(self,item, next= None,prev=None): ##双向链表除了头和尾之外都是双向的

        self.prev = prev

        self.item = item

        self.next = next

    def __repr__(self):

        return '<{}<--{}-->{}>'.format(self.prev.item if self.prev else 'None',self.item,self.next.item if self.next else 'None')

#构造双向链表

class DubleLineked:

    def __init__(self):

        self.head = None

        self.tail = None

        self.size = None

    def append(self,item):

        Node = Node2(item)  ##构造一个要添加的节点 然后写入到链表中

        if self.head is None:

            self.head = Node ##如果是空的直接追加

            #self.tail = Node

        else:

            Node.prev = self.tail

            self.tail.next = Node

        self.tail = Node

        return self

    def insert(self,index,value):

        if index <0 : #只接受正索引

            raise IndexError('Negative index err{}'.format(index))

        current = None

        for i,node in enumerate(self.iterlink()):

            if i == index:

                current = node

                break

        else:

            self.append(value)

            return  ########################## if使用后记得用return 终止函数执行

        ##创建一个待加入节点对象; 如果是空 或者超界的情况 则直接执行append语句 append有包装的语句

        node = Node2(value) #包装成模块

        prev = current.prev

        # next = current.next

        ## 放在头 考虑修正关系  切记 修改后要修改头部 为不加入不用考虑 因为append 就是尾部和空的加入

        if index == 0 : # 除了空和尾部追加 就是 头部 和中部了 分开讨论一下就ok了 i==0 or prev = None

            current.prev = node

            node.next = current

            self.head = node

        else:#中部追加

            node.prev = prev

            node.next = current

            current.prev = node

            prev.next = node

        return

    def pop(self): #尾部移除

        if self.tail is None: #考虑空链表

            raise Exception('{}'.format(None))

        else:

            node = self.tail #取模块

            item = node.item # item 是模块内的data

            prev = node.prev #模块的前一项

            if prev is None and next is None: #只有一个node

                self.head = None

                self.tail = None

                return item  #返回一个数值

            else:##两个元素移除尾部 最后剩下一个

                self.tail = prev ##node.prev

                prev.next = None

                return item   #返回一个数值

    def remove(self,index): #任意位置移除 比较index

        if index <0 :

            raise IndexError("Do not support nagative index {}".format(index))

        if self.head is None or self.tail is None:

            raise Exception('Empty')

        for i,node in enumerate(self.iterlink()):

            if i == index:

                current = node

                break

        else: ##超出索引范围 移除最后一个

            self.pop() #抛出最后一个

            return  ##记得终止函数执行@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

            #raise IndexError('超出索引边界')     两个都可以

        ###break 说明找到了要索引的值 这时候就要对这个值进行操作了

        prev = current.prev

        next = current.next

        item = current.item

        #分4情况

        #就一个模块 既是头 有事尾

        #在开头

        #在结尾

        #在中间

        if prev is None and next is None: #JUEST ONE

            self.head = None

            self.tail = None

        elif prev is None: ##不是一个元素的链表,头部移除 修正头部

            self.head = next ##更改头部

            next.prev = None # 头部指针置空

        elif next is None: ##不是一个元素的链表,说明尾部移除 修正尾部

            self.tail = prev

            prev.next = None

        else: #不是一个元素 且是中间移除 不用修正头和尾

            prev.next = next

            next.prev = prev

    def iterlink(self,reversed = False): #双向迭代就是翻转的问题 想sorted函数

        current = self.head if not reversed else self.tail

        while current:

            yield current

            current = current.next if not reversed else current.prev

#输出结果测试

a = DubleLineked()

a.append(1)

a.append(2)

a.append(3)

a.insert(100,'abd')

a.insert(0,112)

a.insert(3,'liajibin')

a.pop()

print(a.pop())

a.remove(1)

for x in a.iterlink():

    print(x)



推荐阅读
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 根据最新发布的《互联网人才趋势报告》,尽管大量IT从业者已转向Python开发,但随着人工智能和大数据领域的迅猛发展,仍存在巨大的人才缺口。本文将详细介绍如何使用Python编写一个简单的爬虫程序,并提供完整的代码示例。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 主要用了2个类来实现的,话不多说,直接看运行结果,然后在奉上源代码1.Index.javaimportjava.awt.Color;im ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
  • 本文详细介绍了macOS系统的核心组件,包括如何管理其安全特性——系统完整性保护(SIP),并探讨了不同版本的更新亮点。对于使用macOS系统的用户来说,了解这些信息有助于更好地管理和优化系统性能。 ... [详细]
  • 本文介绍了如何通过 Maven 依赖引入 SQLiteJDBC 和 HikariCP 包,从而在 Java 应用中高效地连接和操作 SQLite 数据库。文章提供了详细的代码示例,并解释了每个步骤的实现细节。 ... [详细]
  • 尽管使用TensorFlow和PyTorch等成熟框架可以显著降低实现递归神经网络(RNN)的门槛,但对于初学者来说,理解其底层原理至关重要。本文将引导您使用NumPy从头构建一个用于自然语言处理(NLP)的RNN模型。 ... [详细]
author-avatar
mobiledu2502852147
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有