您的位置:首页 > 理论基础 > 数据结构算法

Python数据结构——队列

2017-03-28 09:50 309 查看
队列


什么是队列

和堆栈类似,唯一的区别是队列只能在队头进行出队操作,所以队列是是先进先出(FIFO, First-In-First-Out)的线性表




特点

先入先出,后入后出
除尾节点外,每个节点有一个后继
(可选)除头节点外,每个节点有一个前驱


操作

push():入队
pop():出队


实现


普通队列

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

class
MyQueue():

    def
__init__(self,
value=None):

        self.value
=
value

        #
前驱

        #
self.before = None

        #
后继

        self.behind
=
None

 

    def
__str__(self):

        if
self.value
is
not
None:

            return
str(self.value)

        else:

            return
'None'

 

 

def
create_queue():

    """仅有队头"""

    return
MyQueue()

 

 

def
last(queue):

    if
isinstance(queue,
MyQueue):

        if
queue.behind
is
not
None:

            return
last(queue.behind)

        else:

            return
queue

 

 

def
push(queue,
ele):

    if
isinstance(queue,
MyQueue):

        last_queue
=
last(queue)

        new_queue
=
MyQueue(ele)

        last_queue.behind
=
new_queue

 

 

def
pop(queue):

    if
queue.behind
is
not
None:

        get_queue
=
queue.behind

        queue.behind
=
queue.behind.behind

        return
get_queue

    else:

        print('队列里已经没有元素了')

 

def
print_queue(queue):

    print(queue)

    if
queue.behind
is
not
None:

        print_queue(queue.behind)

队列的两种主要操作是:向队列中插入新元素和删除队列中的元素。插入操作也叫做入队,删除操作也叫做出队。入队操作在队尾插入新元素,出队操作删除队头的元素。
队列的另外一项重要操作是读取队头的元素。这个操作叫做peek()。该操作返回队头元素,但不把它从队列中删除。除了读取队头元素,我们还想知道队列中存储了多少元素,可以使用size()满足该需求。
queue通常的操作:
Queue()        定义一个空队列,无参数,返回值是空队列。
enqueue(item)  在队列尾部加入一个数据项,参数是数据项,无返回值。
dequeue()      删除队列头部的数据项,不需要参数,返回值是被删除的数据,队列本身有变化。
isEmpty()      检测队列是否为空。无参数,返回布尔值。
size()         返回队列数据项的数量。无参数,返回一个整数。

队列操作举例:
Queue OperationQueue ContentsReturn Value
q.isEmpty()[]True
q.enqueue(4)[4] 
q.enqueue('dog')['dog',4] 
q.enqueue(True)[True,'dog',4] 
q.size()[True,'dog',4]3
q.isEmpty()[True,'dog',4]False
q.enqueue(8.4)[8.4,True,'dog',4] 
q.dequeue()[8.4,True,'dog']4
q.dequeue()[8.4,True]'dog'
q.size()[8.4,True]2
Queue 类模拟:
class Queue:
"""模拟队列"""
def __init__(self):
self.items = []

def isEmpty(self):
return self.items == []

def enqueue(self, item):
self.items.insert(0,item)

def dequeue(self):
return self.items.pop()

def size(self):
return len(self.items)

以下是测试代码:

q=Queue()
q.isEmpty()

q.enqueue('dog')
q.enqueue(4)
q=Queue()
q.isEmpty()

q.enqueue(4)
q.enqueue('dog')
q.enqueue(True)


【队列Queue模块】
创建一个“队列”对象

import Queue
myqueue = Queue.Queue(maxsize = 10)

Queue.Queue类即是一个队列的同步实现。队列长度可为无限或者有限。可通过Queue的构造函数的可选参数maxsize来设定队列长度。如果maxsize小于1就表示队列长度无限。

将一个值放入队列中

myqueue.put(10)

调用队列对象的put()方法在队尾插入一个项目。put()有两个参数,第一个item为必需的,为插入项目的值;第二个block为可选参数,默认为1。如果队列当前为空且block为1,put()方法就使调用线程暂停,直到空出一个数据单元。如果block为0,put方法将引发Full异常。

将一个值从队列中取出

myqueue.get()

调用队列对象的get()方法从队头删除并返回一个项目。可选参数为block,默认为True。如果队列为空且block为True,get()就使调用线程暂停,直至有项目可用。如果队列为空且block为False,队列将引发Empty异常。

python queue模块有三种队列:
1、python queue模块的FIFO队列先进先出。
2、LIFO类似于堆。即先进后出。
3、还有一种是优先级队列级别越低越先出来。 

针对这三种队列分别有三个构造函数:
1、class Queue.Queue(maxsize) FIFO 
2、class Queue.LifoQueue(maxsize) LIFO 
3、class Queue.PriorityQueue(maxsize) 优先级队列 

介绍一下此包中的常用方法:

Queue.qsize() 返回队列的大小 
Queue.empty() 如果队列为空,返回True,反之False 
Queue.full() 如果队列满了,返回True,反之False
Queue.full 与 maxsize 大小对应 
Queue.get([block[, timeout]])获取队列,timeout等待时间 
Queue.get_nowait() 相当Queue.get(False)
非阻塞 Queue.put(item) 写入队列,timeout等待时间 
Queue.put_nowait(item) 相当Queue.put(item, False)
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作

 

 

附上一个例子:

#coding:utf-8

import Queue

import threading

import time

import random

q = Queue.Queue(0) #当有多个线程共享一个东西的时候就可以用它了

NUM_WORKERS = 3

class MyThread(threading.Thread):

    def __init__(self,input,worktype):

       self._jobq = input

       self._work_type = worktype

       threading.Thread.__init__(self)

    def run(self):

       while True:

           if self._jobq.qsize() > 0:

               self._process_job(self._jobq.get(),self._work_type)

           else:break

    def _process_job(self, job, worktype):

       doJob(job,worktype)

def doJob(job, worktype):

   time.sleep(random.random() * 3)

    print"doing",job," worktype ",worktype

if __name__ == '__main__':

    print "begin...."

    for i inrange(NUM_WORKERS * 2):

       q.put(i) #放入到任务队列中去

    print "job qsize:",q.qsize()

    for x inrange(NUM_WORKERS):

       MyThread(q,x).start()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: