前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python实现双端队列

Python实现双端队列

作者头像
Python碎片公众号
发布2021-02-26 15:50:54
7010
发布2021-02-26 15:50:54
举报
文章被收录于专栏:Python碎片公众号的专栏

关于双端队列的介绍,请参考:栈和队列简介

双端队列的数据存储结构可以是顺序表,也可以是链表,本篇文章使用 Python 来分别实现顺序双端队列和链双端队列。

一、实现顺序双端队列

顺序双端队列是使用顺序表存储数据的双端队列,Python 中的列表元组都属于顺序表,下面使用列表来存储数据,实现顺序双端队列。

代码语言:javascript
复制
# coding=utf-8
class SequenceDoubleQueue(object):

    def __init__(self):
        self.__members = list()

    def is_empty(self):
        return not len(self.__members)

    def show(self):
        if self.is_empty():
            print('双端队列为空')
            return
        for member in self.__members:
            if self.__members.index(member) != len(self.__members)-1:
                print(member, end='|')
            else:
                print(member)

    def head_enter(self, data):
        self.__members.insert(0, data)

    def end_enter(self, data):
        self.__members.append(data)

    def head_outer(self):
        if self.is_empty():
            return
        return self.__members.pop(0)

    def end_outer(self):
        if self.is_empty():
            return
        return self.__members.pop()

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

    def check(self, index):
        if index < 0 or index > len(self.__members)-1:
            raise IndexError
        return self.__members[index]

定义一个 SequenceDoubleQueue() 类,实例化的时候会创建一个空列表,生成一个空的顺序双端队列。Python 中的列表有很多自带的方法,所以将存储数据的列表设置成私有属性,避免用户在类外面链式调用列表的其他方法。如果用户直接在类外面操作列表,则双端队列只能从两端存取数据的规则可能会被破坏。

下面是顺序双端队列的各个方法实现:

is_empty(): 判断顺序双端队列是否为空。如果存储数据的列表长度为零(对应布尔值False),则顺序双端队列为空(is_empty为True),反之。

show(): 展示顺序双端队列中的数据,也就是将双端队列中所有的数据依次打印输出,对存储数据的列表遍历输出即可。

head_enter(data): 前端入队,也就是从队列的前端添加数据到队列中。在本文中,统一将列表的开头当成双端队列的前端,列表的结尾当成双端队列的后端。前端入队调用列表的 insert(0, data) 方法即可。

end_enter(data): 后端入队,也就是从队列的后端添加数据到队列中。后端入队调用列表的 append(data) 方法即可。

head_outer(): 前端出队,也就是从队列中取出前端的数据,并将取出的数据返回。前端出队调用列表的 pop(0) 方法即可。

end_outer(): 后端出队,也就是从队列中取出后端的数据,并将取出的数据返回。后端出队调用列表的 pop() 方法即可。

length(): 返回顺序双端队列的长度。顺序双端队列的长度就是存储数据的列表长度。

check(index): 返回顺序双端队列中指定位置的数据。根据指定的 index 值,将存储数据的列表中对应索引的数据返回即可。

代码语言:javascript
复制
if __name__ == '__main__':
    sdq = SequenceDoubleQueue()
    print("is_empty: ", sdq.is_empty())
    sdq.show()

    sdq.head_enter('x')
    sdq.head_enter('y')
    sdq.head_enter('z')
    sdq.end_enter(10)
    sdq.end_enter(20)
    sdq.end_enter(30)
    sdq.show()
    print(sdq.head_outer())
    print(sdq.end_outer())
    sdq.show()

    print("sequence double queue length: ", sdq.length())
    print("index member is: ", sdq.check(2))

运行结果:

代码语言:javascript
复制
is_empty:  True
双端队列为空
z|y|x|10|20|30
z
30
y|x|10|20
sequence double queue length:  4
index member is:  10

二、实现链双端队列

链双端队列是使用链表存储数据的双端队列,链表是逻辑有序的,由一个一个的节点构成,所以先声明一个创建节点的类。

代码语言:javascript
复制
class Node(object):

    def __init__(self, data):
        self.data = data
        self.next = None

下面按照单向链表的方式来实现链双端队列。

代码语言:javascript
复制
class LinkDoubleQueue(object):

    def __init__(self):
        self.__head = None

    def is_empty(self):
        return not self.__head

    def show(self):
        if self.is_empty():
            print('双端队列为空')
            return
        cur = self.__head
        while cur is not None:
            if cur.next is not None:
                print(cur.data, end='|')
            else:
                print(cur.data)
            cur = cur.next

    def head_enter(self, data):
        node = Node(data)
        node.next = self.__head
        self.__head = node

    def end_enter(self, data):
        if self.is_empty():
            self.head_enter(data)
            return
        node = Node(data)
        cur = self.__head
        while cur.next is not None:
            cur = cur.next
        cur.next = node

    def head_outer(self):
        if self.is_empty():
            return
        cur = self.__head
        self.__head = self.__head.next
        return cur.data

    def end_outer(self):
        if self.is_empty():
            return
        cur = self.__head
        prev = None
        while cur.next is not None:
            prev = cur
            cur = cur.next
        if cur == self.__head:
            self.__head = self.__head.next
            return
        prev.next = cur.next
        return cur.data

    def length(self):
        length = 0
        cur = self.__head
        while cur is not None:
            length += 1
            cur = cur.next
        return length

    def check(self, index):
        if index < 0 or index >= self.length():
            raise IndexError
        cur = self.__head
        for _ in range(index):
            cur = cur.next
        return cur.data

定义一个 LinkDoubleQueue() 类,实例化的时候会创建一个空链表,生成一个空的链双端队列。

下面是链双端队列的各个方法实现:

is_empty(): 判断链双端队列是否为空。如果存储数据的链表头指向空(对应布尔值False),则链双端队列为空(is_empty为True),反之。

show(): 展示链双端队列中的数据,也就是将双端队列中所有的数据依次打印输出,对存储数据的链表遍历输出即可。

head_enter(data): 前端入队,也就是从队列的前端添加数据到队列中。在本文中,统一将链表的头当成双端队列的前端,链表的尾当成双端队列的后端。前端入队就是从链表头部添加节点。

end_enter(data): 后端入队,也就是从队列的后端添加数据到队列中。后端入队就是从链表尾部添加节点。

head_outer(): 前端出队,也就是从队列中取出前端的数据,并将取出的数据返回。前端出队就是删除并返回链表头节点的数据。

end_outer(): 后端出队,也就是从队列中取出后端的数据,并将取出的数据返回。后端出队就是删除并返回链表尾节点的数据。

length(): 返回链双端队列的长度。链双端队列的长度就是存储数据的链表长度。

check(index): 返回链双端队列中指定位置的数据。根据指定的 index 值,找到并返回链表中对应位置的节点数据。

代码语言:javascript
复制
    ldq = LinkDoubleQueue()
    print("is_empty: ", ldq.is_empty())
    ldq.show()

    ldq.head_enter('X')
    ldq.head_enter('Y')
    ldq.head_enter('Z')
    ldq.end_enter(100)
    ldq.end_enter(200)
    ldq.end_enter(300)
    ldq.show()
    print(ldq.head_outer())
    print(ldq.end_outer())
    ldq.show()

    print("link queue length: ", ldq.length())
    print("index member is: ", ldq.check(2))

运行结果:

代码语言:javascript
复制
is_empty:  True
双端队列为空
Z|Y|X|100|200|300
Z
300
Y|X|100|200
link queue length:  4
index member is:  100

以上就是用 Python 实现的顺序双端队列及链双端队列。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python 碎片 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档