[笔记]python数据结构之线性表:linkedlist链表,stack栈,queue队列

2023-05-16


python数据结构之线性表  

python内置了很多高级数据结构,list,dict,tuple,string,set等,在使用的时候十分舒心。但是,如果从一个初学者的角度利用python学习数据结构时,这些高级的数据结构可能给我们以迷惑。
比如,使用list实现queue的时候,入队操作append()时间复杂度可以认为是O(1),但是,出队操作pop(0)的时间复杂度就是O(n)。
如果是想利用python学学数据结构的话,我觉得还是自己实现一遍基本的数据结构为好。

1.链表

在这里,我想使用类似于c语言链式存储的形式,借助于class,分别构成无序链表以及有序链表。
我们先看看链表节点的定义:
class ListNode(object):
    def __init__(self, data):
        self.data = data
        self.next = None

    def getData(self):
        return self.data

    def setData(self, newData):
        self.data = newData

    def getNext(self):
        return self.next

    def setNext(self, nextNode):
        self.next = nextNode
利用链表节点,组成无序链表类:
class UnorderedList(object):
    def __init__(self):
        self.head = None

    def getHead(self):
        return self.head

    def isEmpty(self):
        return self.head is None

    def add(self, item):
        node = ListNode(item)
        node.next = self.head
        self.head = node   # the head is the most recently added node

    def size(self):
        current = self.head
        count = 0
        while current is not None:
            count += 1
            current = current.getNext()

        return count

    def search(self, item):
        current = self.head
        found = False
        while current is not None and not found:
            if current.getData() == item:
                found = True
            else:
                current = current.getNext()
        return found

    def append(self, item):
        node = ListNode(item)
        if self.isEmpty():
            self.head = node
        else:
            current = self.head
            while current.getNext() is not None:
                current = current.getNext()
            current.setNext(node)

    def remove(self, item):
        current = self.head
        previous = None
        found = False
        while not found:
            if current.getData() == item:
                found = True
            else:
                previous = current
                current = current.getNext()

        if previous is None:
            self.head = current.getNext()
        else:
            previous.setNext(current.getNext())
在上面的链表中,每次添加元素都直接添加在链表头部,add()的时间复杂度为O(1),而append()操作在队尾,其时间复杂度为O(n)。有没有前后加入操作的时间复杂度都为O(1)的链表呢,当然是有的:
class UnorderedList(object):
    def __init__(self):
        self.head = None
        self.tail = None

    def getHead(self):
        return self.head

    def isEmpty(self):
        return self.head is None and self.tail is None

    def add(self, item):
        node = ListNode(item)
        if self.isEmpty():
            self.head = self.tail = node
        else:
            node.next = self.head
            self.head = node   # the head is the most recently added node

    def size(self):
        current = self.head
        count = 0
        while current is not None:
            count += 1
            current = current.getNext()

        return count

    def search(self, item):
        current = self.head
        found = False
        while current is not None and not found:
            if current.getData() == item:
                found = True
            else:
                current = current.getNext()
        return found

    def append(self, item):
        node = ListNode(item)
        self.tail.setNext(node)
        self.tail = node

    def remove(self, item):
        current = self.head
        previous = None
        found = False
        while not found:
            if current.getData() == item:
                found = True
            else:
                previous = current
                current = current.getNext()

        if current.getNext() is None:
            self.tail = previous

        if previous is None:
            self.head = current.getNext()
        else:
            previous.setNext(current.getNext())
对无序链表类加入一个属性,引用链表末尾节点,即可。做出了这样的改变,在add和remove操作也应作出相应变化。
下面再看看有序链表。有序链表在插入节点的时候便寻找适合节点的位置。
class OrderedList(object):
    def __init__(self):
        self.head = None

    def isEmpty(self):
        return self.head is None

    def search(self, item):
        stop = False
        found = False
        current = self.head
        while current is not None and not found and not stop:
            if current.getData() > item:
                stop = True
            elif current.getData() == item:
                found = True
            else:
                current = current.getNext()
        return found

    def add(self, item):
        previous = None
        current = self.head
        stop = False
        while current is not None and not stop:
            if current.getData() >item:
                stop = True
            else:
                previous = current
                current = current.getNext()
        node = ListNode(item)
        if previous is None:
            node.getNext(current)
            self.head = node
        else:
            previous.setNext(node)
            node.setNext(current)

2.栈stack

对于栈来说,python内置的列表已经可以满足栈的要求。
入栈操作为append(),出栈操作为pop()。它们的时间复杂度都为O(1).
class Stack(object):
    def __init__(self):
        self._items = []

    def is_empty(self):
        return self._items == []

    def push(self, item):
        self._items.append(item)

    def pop(self):
        return self._items.pop()

    def peek(self):
        return self._items[-1]
当然了,我们也可以自己实现链栈,跟链表的实现类似。
class StackNode(object):
    """docstring for StackNode"""
    def __init__(self, value):
        self.value = value
        self.next = None


class Stack(object):
    """docstring for Stack"""
    def __init__(self, top=StackNode(None)):
        self.top = top
    
    def get_top(self):
        return self.top

    def is_empty(self):
        return self.top.value is None

    def push(self, val):
        node = StackNode(val)
        node.next = self.top
        self.top = node
        return

    def pop(self):
        if self.is_empty():
            print("Stack is Empty, cannot pop anymore.\n")
            return
        node = self.top
        self.top = self.top.next
        return node

3.队列queue

队列如果利用链表实现的话会,出现文章开头提及的问题。
所以队列可以用链表实现。
class QueueNode(object):
    def __init__(self, value):
        self.value = value
        self.next = None


class Queue(object):
    def __init__(self):
        self.front = None
        self.rear = None

    def is_empty(self):
        return self.front is None and self.rear is None

    def enqueue(self, num):
        node = QueueNode(num)
        if self.is_empty():
            self.front = node
            self.rear = node
        else:
            self.rear.next = node
            self.rear = node

    def dequeue(self):
        if self.front is self.rear:
            node = self.front
            self.front = None
            self.rear = None
            return node.value
        else:
            node = self.front
            self.front = node.next
            return node.value
在python的库中,比如collections以及Queue中都有deque模块。
deque模块顾名思义,可以做双端队列。所以,deque模块也可以做队列,和栈。
dq = deque([1,2,3,4,5,6,7,8,9])
dq.pop() # pop 9
dq.popleft() #pop 1
dq.apend(9) # append 9
dq.appendleft(1) #insert 1 in index 0
在多线程,多进程编程时,经常使用Queue模块的Queue类。
其实:假设q=Queue.Queue() 
那么 q.queue就是一个deque。
这个以后再谈。







本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[笔记]python数据结构之线性表:linkedlist链表,stack栈,queue队列 的相关文章

随机推荐

  • Halcon中count_obj算子及其异常分析

    count obj算子 count obj算子是用来计算输入区域中连通域的个数 更直观的说法是 xff0c 计算Region中有几个单独的区域 一般用在connection算子之后 xff0c 该算子的作用是将输入区域分割成单独的连通域 异
  • Halcon中 reduce_domain算子和crop_domain算子的使用及配合

    1 reduce domain算子 reduce domain span class hljs keyword Image span Region ImageReduced 其中 xff0c span class hljs keyword
  • 卷帘曝光和全局曝光的差别

    全局曝光和卷帘曝光是常见的相机曝光方式 一般来说 xff0c CCD相机是全局曝光 xff0c 而CMOS相机则存在卷帘曝光 那么 xff0c 这两种方式孰优孰劣呢 xff1f 或者说 xff0c 他们两者的差别在哪里呢 xff1f 那么
  • 自动化设备的软件框架

    自动化设备的软件主要由2部分组成 xff1a 1是运动控制部分的软件实现 xff0c 2是上位机处理数据并显示结果的软件实现 运动控制的实现 第1部分的实现主要有2种方式 xff0c 一种是用板卡控制的方式 xff0c 一种是用PLC控制的
  • Halcon中两种实现旋转的方法rotate_image和affine_trans_image

    Halcon中实现旋转的方式由两种 一种是rotate image xff0c 该方式实现简单 xff0c 但只能绕中心旋转 二是affine trans image xff0c 该方式实现较复杂 xff0c 但是可以实现绕任意位置的旋转
  • 一文搞定深度学习入门级电脑硬件配置

    对于刚接触深度学习的学友而言 xff0c 可能都会碰到电脑配置的问题 xff0c 比如显卡型号 内存容量 处理器型号等 好的电脑配置 xff0c 比如GPU加速的显卡 xff0c 是能够有效缩短算法的训练时间的 xff0c 这能让人尽快的看
  • 一文详解numpy中np.nonzero()函数

    np nonzero函数是numpy中用于得到数组array中非零元素的位置 xff08 数组索引 xff09 的函数 一般来说 xff0c 通过help xff08 np nonzero xff09 能够查看到该函数的解析与例程 但是 x
  • Matlab笔记:将列向量直接赋值给行向量

    在别人的matlab代码中看到 xff0c 将列向量赋值给行向量 最初还以为是别人的代码有bug xff0c 实际上运行后才发现是由自己的无知造成的 因此 xff0c 将如下一小段测试的代码贴出来 xff0c 向量的维度由左值 xff08
  • 使用已训练好的caffe模型的步骤

    如何使用生成的模型 xff0c 可能是在训练好模型之后 xff0c 需要考虑的问题 实际上 xff0c caffe是存在两种接口来进行调用模型 xff1a 1种是基于python的 xff0c 另一种则是基于c 43 43 的 我个人是倾向
  • 怎么开发爬虫软件?

    怎么开发爬虫软件 xff1f 来自 ITPUB博客 xff0c 链接 xff1a http blog itpub net 69941520 viewspace 2650981 xff0c 如需转载 xff0c 请注明出处 xff0c 否则将
  • 来聊聊ios下的url缓存问题

    一 关于同一个url的多次请求 有时候 xff0c 对同一个URL请求多次 xff0c 返回的数据可能都是一样的 xff0c 比如服务器上的某张图片 xff0c 无论下载多少次 xff0c 返回的数据都是一样的 01220830391450
  • openstack ovs-vswitch收包流程

    数据包从物理网卡进入虚拟机的流程 物理网卡处理 NIC 收到数据包 xff0c 会先将高低电信号转换到网卡 FIFO 存储器 NIC 首先申请 Ring buffer 的描述 xff0c 根据描述找到具体的物理地址 xff0c NIC 会使
  • 9个常用的Shell脚本

    1 Dos 攻击防范 xff08 自动屏蔽攻击 IP xff09 bin bash DATE 61 date 43 d b Y H M LOG FILE 61 usr local nginx logs demo2 access log AB
  • google breakpad /qbreakpad 在 arm移植

    google breakpad qbreakpad 在 arm移植 breakpad在arm linux上移植 xff0c 集成到qt中生成qbreakpad 参考文档 xff1a Google Breakpad 之一 xff0c 跨平台c
  • 无限递归(与无限循环一样)

    public int sumByMax int max if max lt 61 2 return max 43 sumByMax max 1 else return max
  • [leetcode] Maximum Split of Positive Even Integers

    Maximum Split of Positive Even Integers You are given an integer finalSum Split it into a sum of a maximum number of uni
  • [flask]基础知识

    Flask 基础知识 基本框架结构 span class token keyword from span flask span class token keyword import span Flask span class token k
  • 解决mybatis 报错java.lang.UnsupportedOperationException

    解决mybatis中mapper xml 报错java lang UnsupportedOperationException 主要是mapper xml里中的select语句对应的 resultType应该为对应的实体类 比如 xff0c
  • 用Python计算北京地铁的两站间最短换乘路线

    用Python计算北京地铁的两站间最短换乘路线 地铁数据 地铁数据用字典表示 xff1a station neighbor1 line number neighbor2 line number station2 现在我们有地铁的站名 xff
  • [笔记]python数据结构之线性表:linkedlist链表,stack栈,queue队列

    python数据结构之线性表 python内置了很多高级数据结构 xff0c list xff0c dict xff0c tuple xff0c string xff0c set等 xff0c 在使用的时候十分舒心 但是 xff0c 如果从