• 数据结构——线性结构(链表)


      链表定义:链表是由一系列节点组成的元素结合。每个节点包含两个部分,数据域item指向下一个节点的指针next。通过节点之间的相互连接,最终串联成一个链表。

    一、单链表

      

    1、节点定义

    class Node:
        def __init__(self, item):
            self.item = item
            self.next = None
    
    # 模拟链表
    a = Node(1)
    b = Node(2)
    c = Node(3)
    a.next = b
    b.next = c
    
    print(a.next.next.item)   # 输出:3
    

    2、建立链表

    (1)头插法

      头插法是在头结点这边插入。

      

    (2)尾插法

      不光要知道头还需要知道尾在哪。从尾节点插入。

      

    (3)代码实现 

    class Node:
        def __init__(self, item):
            self.item = item    # 存放数据
            self.next = None   # 指针,指向下一个节点
    
    
    def create_linklist_head(li):
        """头插法创建链表"""
        head = Node(li[0])    # 头节点
        for element in li[1:]:   # 从第二个到最后一个遍历列表
            node = Node(element)    # 实例化为一个链表节点
            node.next = head     # 设置实例的next属性指向链表头节点
            head = node      # 将新加入链表节点设置为头节点
        return head      # 要遍历链表需要从头往回找
    
    
    def create_linklist_tail(li):
        """尾插法创建链表"""
        head = Node(li[0])   # 创建头节点对象
        tail = head          # 尾节点也是头节点
        for element in li[1:]:    # 从第二个到最后一个遍历列表
            node = Node(element)    # 创建一个新链表节点
            tail.next = node    # 设置实例next属性指向链表尾节点
            tail = node      # 将新加入链表的节点设置为尾节点
        return head      # 返回头节点,可以从头往回找
    
    
    def print_linklist(lk):
        """打印链表"""
        while lk:   # 只要lk存在
            print(lk.item, end=',')    # 打印链表值
            lk = lk.next      # 到最后一个节点的时候,lk.next属性为空退出循环
    
    
    lk = create_linklist_head([1, 2, 3])
    print(lk)
    print_linklist(lk)
    """
    <__main__.Node object at 0x10402de48>
    3,2,1,
    """
    
    lk2 = create_linklist_tail([1, 3, 6, 8, 9])
    print_linklist(lk2)
    """
    3,2,1,1,3,6,8,9,
    """
    

    3、链表的遍历

      

    4、链表节点的插入和删除(视频缺,需要补)

    二、双链表

      双链表的每个节点有两个指针:一个指向后一个节点,另一个指向前一个节点。

      

    1、节点定义

    class Node(object):
        def __init__(self, item):
            self.item = item    # 数据
            self.next = None   # 指针,指向后一个节点
            self.prior = None   # 指针,指向前一个节点
    

    2、双链表节点插入

    #插入
    p.next = curNode.next
    curNode.next.prior = p 
    p.prior = curNode
    curNode.next = p
    

      代码过程图示如下:

    (1)p.next = curNode.next   让p.next指针指向curNode下一个节点

      

    (2)curNode.next.prior = p  让curNode下一个节点的prior指针指向p

      

    (3)p.prior = curNode   让p的prior指针指向curNode

      

    (4)curNode.next = p  让curNode的next指针指向p

      

    3、双链表节点的删除

    #删除
    p = curNode.next
    curNode.next = p.next
    p.next.prior = curNode
    del p
    

      代码过程图示如下:

    (1)p = curNode.next  指定要删除的节点是curNode的next指针指向的节点

      

    (2)curNode.next = p.next  修改curNode的next指针指向要删除节点的next指针指向的节点

      

    (3)p.next.prior = curNode  修改p的next指针指向的节点的prior指针,将指针指向curNode

      

    (4)del p    删除p

    三、链表总结

    1、顺序表(列表)与 链表复杂度对比分析

      按元素值查找时:都是挨个查看,时间复杂度都为O(n)

      按下标查找时:顺序表更快,直接插入到对位位置。链表则需要从头开始数。链表时间复杂度是O(n),顺序表时间复杂度是O(1)。

      在某元素后插入:这种情况顺序表是O(n),插入后,后面的元素都需要往后挪。链表则是O(1)。

      删除某元素:这种情况顺序表是O(n),删除后,后面的元素都需要往前挪。链表则是O(1)。

    2、链表和顺序表对比总结

      链表在插入和删除操作上明显快于顺序表

      链表的内存可以更灵活的分配。java等的数组一开始申请的空间如果满了是没有办法解决的,python的列表在一开始申请的空间不足时,也是通过重新申请新的空间,将原来内存空间的内容拷贝进去。

        可以尝试利用链表重新实现栈和队列,使用栈实现队列就不用考虑队满的问题,也不用设计为环形。

      链表这种链式存储的数据结构对树和图的结构有很大的启发性。

      

     

  • 相关阅读:
    11.【原创】Object.keys()的一般用法
    5. 【原创】table设置text-overflow: ellipsis;(超出范围显示...)不生效
    12.【转载】vscode默认常用快捷键
    13.【原创】JS读取apk安装包的信息,做应用上传
    11.【原创】chrom文件上传后,手动释放内存
    26.Mysql "truncate"与"delete"的区别
    25.【转载】Mysql timestamp类型字段的CURRENT_TIMESTAMP与ON UPDATE CURRENT_TIMESTAMP属性
    bof
    ctf Wiener tricky
    分解大素数
  • 原文地址:https://www.cnblogs.com/xiugeng/p/9695235.html
Copyright © 2020-2023  润新知