精华内容
下载资源
问答
  • 为什么java优先级队列排序结果错误?
    2022-04-16 18:35:24

    PriorityQueue是二叉小顶堆, 并不是完全有序的. 只能保证第一个元素是最小的而已.

    如果你想遍历得到有序结果应该调用poll方法, 其原理可以参考堆排序.

    另外如果只是想排序并不用那么复杂, 构建普通的数组, 然后array.sort就好了, java内部会帮你调用timsort.

    更多相关内容
  • I was trying to insert the integers in PriorityQueue, and I know that :If no comparator is specified when a PriorityQueue is constructed, then the defaultcomparator for the type of data stored in the ...

    I was trying to insert the integers in PriorityQueue, and I know that :

    If no comparator is specified when a PriorityQueue is constructed, then the default

    comparator for the type of data stored in the queue is used. The default comparator will order

    the queue in ascending order

    However, the output I am getting is not in sorted order.

    Output after running the below code is : [2, 4, 8, 6]

    public static void main(String args[]) {

    PriorityQueue q = new PriorityQueue(10);

    q.offer(4);

    q.offer(2);

    q.offer(8);

    q.offer(6);

    System.out.print(q);

    }

    Can someone please explain why ?

    解决方案

    A PriorityQueue is what is called a binary heap. It is only ordered/sorted in the sense that the first element is the least. In other word, it only cares about what is in the front of the queue, the rest are "ordered" when needed.

    The elements are only ordered as they are dequeued, i.e. removed from the queue using poll(). This is the reason why a PriorityQueue manages to have such good performance, as it is not doing any more sorting than it needs at any time.

    If you want to know how heaps work in detail I recommend this MIT lecture on heaps.

    展开全文
  • 可以认为优先级队列是一种修改过的普通队列:普通队列依据记录插入的时间来获取下一个记录,而优先级队列依据优先级来获取下一个记录,优先级取决于排序字段的值。优先级队列常用来解决调度问题,比如...

    微信公众号:冰咖啡与狗

    1. 什么是优先级队列?

    优先级队列是一种容器型数据结构,它能管理一队记录,并按照排序字段(例如一个数字类型的权重值)为其排序。由于是排序的,所以在优先级队列中你可以快速获取到最大的和最小的值。

    可以认为优先级队列是一种修改过的普通队列:普通队列依据记录插入的时间来获取下一个记录,而优先级队列依据优先级来获取下一个记录,优先级取决于排序字段的值。

    优先级队列常用来解决调度问题,比如给紧急的任务更高的优先级。以操作系统的任务调度为例:高优先级的任务(比如实时游戏)应该先于低优先级的任务(比如后台下载软件更新)执行。

    在 Python 中,内置的标准库提供了两种实现优先队列的数据结构,分别是 heapq 模块和 PriorityQueue 模块,接下来本文将对如何利用这两个数据结构实现优先级队列进行介绍,包括高优先级队列、低优先级队列,以及面向对象的优先级队列。这两种数据结构,其本质都是利用了堆的数据结构来实现优先队列,因此最后会利用列表来实现一个堆排序,然后在实现优先级队列。

    先简单介绍 heap(堆)的概念。堆,是对于每一个父节点上的值都小于或等于子节点的值的二叉树。此外,一个堆必须是一个完整的二叉树,除了最底层,其他每一级必须是被完整填充的。因此,堆的最重要的一个特点就是:首项 heap[0] 总是最小的一项。

    2. heapq 模块

    heapq 是一个二叉堆的实现,其内部使用内置的 list 对象,对于列表中的每一个元素,其满足 a[k] <= a[2*k+1] and a[k] <= a[2*k+2] ,因此,该方法默认的是一个最小堆,a[0] 为队列中的最小元素。

    2.1. 最小优先队列实现

    由于 heapq 模块默认的就是最小堆结构,所以可以直接利用其中的函数操作来实现最小优先队列的功能。

    def smallest_queue(arr):

    """默认为最小优先队列"""

    print("原数组:{0}".format(arr))

    # 将给定的列表转化为最小堆,线性时间

    heapq.heapify(arr)

    print("最小堆数组:{0}".format(arr))

    # 插入元素

    heapq.heappush(arr, 5)

    print("插入新元素后:{0}".format(arr))

    # 弹出最小元素

    item0 = heapq.heappop(arr)

    print("弹出的元素后:{0}".format(arr))

    # 返回最小元素

    item1 = arr[0]

    print("获取最小元素的值:{0}".format(item1))

    # 弹出最小元素,并插入一个新的元素,相当于先 heappop, 再 heappush

    item2 = heapq.heapreplace(arr, -2)

    print("弹出的元素为:{0}".format(item2))

    print("现在的堆结构为:{0}".format(arr))

    2.2. 最大优先队列的实现

    除了最小堆以外,最大堆也是我们常用的一种数据结构,利用 heapq 模块可以实现最大堆的一些简单操作。

    def largest_queue(arr):

    """最大优先队列的实现阅读 heapq 模块的源代码可以发现,其内置了最大优先队列的实现函数和操作函数,但没有内置新插入元素的函数"""

    print("原数组:{0}".format(arr))

    # 将给定的列表转化为最大堆,线性时间

    heapq._heapify_max(arr)

    print("最大堆数组:{0}".format(arr))

    # 弹出最大元素

    item0 = heapq._heappop_max(arr)

    print("弹出的元素为:{0}".format(item0))

    print("弹出的元素后:{0}".format(arr))

    # 弹出最大元素,并插入一个新的元素

    item1 = heapq._heapreplace_max(arr, 9)

    print("弹出的元素为:{0}".format(item1))

    print("现在的堆结构为:{0}".format(arr))

    2.3. 复杂结构的优先队列

    在现实场景中,我们在使用优先队列时往往不是针对简单的数组进行优先排列,而是对元组、列表或者字典等一个个复杂的对象进行优先排列。下面以元组为例,其在构建优先队列时,默认是以第一个元素来进行排列,当第一个元素相同时,则开始比较第二个。字符串的比较从首字母开始进行比较。

    def object_queue():

    """针对对象结构的优先队列"""

    q = []

    heapq.heappush(q, (2, 'code'))

    heapq.heappush(q, (1, 'eat'))

    heapq.heappush(q, (3, 'sleep'))

    heapq.heappush(q, (2, 'play'))

    heapq.heappush(q, (3, "debug"))

    q1 = [x for x in q]

    while q:

    next_item = heapq.heappop(q)

    print(next_item)

    # ---- result -----

    # (1, 'eat')

    # (2, 'code')

    # (2, 'play')

    # (3, 'debug')

    # (3, 'sleep')

    # 返回最小的 n 个元素,相当于 sorted(iterable, key=key)[:n]

    n_smallest = heapq.nsmallest(3, q1, key=lambda x: x[0])

    print("最小的3个元素:{0}".format(n_smallest))

    # 返回最大的 n 个元素,相当于 sorted(iterable, key=key, reverse=True)[:n]

    n_largest = heapq.nlargest(3, q1, key=lambda x: x[1])

    print("最大的3个元素:{0}".format(n_largest))

    3. PriorityQueue 模块

    该模块定义的优先级队列,其内部使用了 heapq 模块,所以它的时间复杂度和heapq是相同的。

    当一个对象的所有元素都是可比较的时,默认情况下是根据队列中的对象的第一个元素进行排序,越小的优先级越高,排在越前面。当第一个元素相同时,依次比较后续的元素的大小来进行排序。

    由于 PriorityQueue 是继承自 Queue 类,所以很多函数的用法可以直接参照于 Queue 类中的函数。

    from queue import PriorityQueue as PQ

    pq = PQ()

    pq.put((1, 'a'))

    pq.put((2, 'c'))

    pq.put((2, 'b'))

    pq.put((2, 'b'))

    print(pq.queue) # [(1, 'a'), (2, 'b'), (2, 'b'), (2, 'c')]

    item0 = pq.get() # (1, 'a')

    print(pq.queue) # [(2, 'b'), (2, 'b'), (2, 'c')]

    print(pq.qsize()) # 优先队列的尺寸

    while not pq.empty():

    print(pq.get())与 heapq 模块不同的是,PriorityQueue 是基于类实现的,其提供的操作是同步的,提供锁操作,支持并发的生产者和消费者。

    4. 实现自己的优先队列

    在面向对象的编程过程中,我们通常是将一些单独的函数或变量组合成一个对象,然后在进行优先级排列。例如我们现在有很多种汽车,汽车有名字和价格,以及一些操作方法。当我们对汽车对象来按照价格进行优先级排列时,由于自定义的对象是不可比较的,所以在进行优先级排列时会报错。因此对于那些自定义的对象,我们需要重写优先级队列的方法来进行实现。

    由于 PriorityQueue 也是基于 heapq 实现的,所以我们自定义的优先级队列可以直接基于 heapq 模块来实现。

    import heapq

    class My_PriorityQueue(object):

    def __init__(self):

    self._queue = []

    self._index = 0

    def push(self, item, priority):

    """队列由 (priority, index, item) 形式组成priority 增加 "-" 号是因为 heappush 默认是最小堆index 是为了当两个对象的优先级一致时,按照插入顺序排列"""

    heapq.heappush(self._queue, (-priority, self._index, item))

    self._index += 1

    def pop(self):

    """弹出优先级最高的对象"""

    return heapq.heappop(self._queue)[-1]

    def qsize(self):

    return len(self._queue)

    def empty(self):

    return True if not self._queue else False

    class Car(object):

    def __init__(self, name, value):

    self.name = name

    self.value = value

    def __repr__(self):

    return "{0}--{1}".format(self.name, self.value)

    if __name__ == "__main__":

    car1 = Car("BMW", 45)

    car2 = Car("Maybach", 145)

    car3 = Car("Bugatti", 85)

    car4 = Car("Cadillac", 78)

    car5 = Car("Maserati", 85)

    pq = My_PriorityQueue()

    pq.push(car1, car1.value)

    pq.push(car2, car2.value)

    pq.push(car3, car3.value)

    pq.push(car4, car4.value)

    pq.push(car5, car5.value)

    print("队列大小:{0}".format(pq.qsize()))

    # 弹出元素

    while not pq.empty():

    print(pq.pop())

    5. 源码文件

    展开全文
  • 前言 这里,我们的优先级队列是涉及到了一个key-value对的。 组合设计模式

    前言

    这里,我们的优先级队列是涉及到了一个key-value对的,其中key是我们的优先级,value是对象。

    首先介绍一下优先级队列吧,是一个应用范围比队列广很多的数据结构,其实用堆来做比较好,这部分介绍的是双向链表。
    如果对双向链表有问题,看这里

    基本结构

    首先给出一个基类

    class PriorityQueueBase():
        """Abstract base class for a priority queue"""
        class _Item():
            """lightweight composite to store priority queue items"""
            __slots__ = '_key', '_value'
            def __init__(self,k,v):
                self._key = k
                self._value = v
            def __lt__(self,other):
                # 这样就可以直接比较两个结点,而不需要比较key
                return self._key < other._key
        def is_empty(self):
            """retrun True if the priority queue is empty"""
            return len(self)==0
    

    很简单,内部有一个item的类存储每一个结点key、value,并重载了大小比较运算符,方便我们就行比较。
    还有一个is_empty函数,都是常用的。

    具体实现

    这里的实现分为两种,排序列表和未排序列表。
    顾名思义,就是我们存储的列表(其实是双向链表)是否有序,如果是无序列表,查找为O(n);如果有序,插入为O(n)。

    直接贴代码,加上注释没什么问题:

    # 未排序列表,查找删除代价大
    class UnsortedPriorityQueue(PriorityQueueBase):
        """a min-oriented priority queue implemented with an unsorted list"""
        def __init__(self):
            """Create a new empty Priority Queue"""
            # 这个是双向链表
            self._data = PositionalList()
        def __len__(self):
            """return the number of items in the priority queue"""
            return len(self._data)
        def add(self,key,value):
            """add a key-value pair"""
            # 双向链表的一个尾插法
            self._data.add_last(self._Item(key,value))
        def _find_min(self):
            """rturn position of item with minimum key"""
            if self.is_empty():
                raise Empty('Priority queue is empty')
            small = self._data.first()
            walk = self._data.after(small)
            # 最小的初始为第一个,然后遍历(通过walk)
            while walk is not None:
                if walk.element() < small.element():
                    small = walk
                walk = self._data.after(walk)
            return small
        def min(self):
            """return but do not remove (k,v) tuple with minimum key"""
            p = self._find_min()
            item = p.element()
            return (item._key,item._value)
        def remove_min(self):
            """remove and return (k,v) tuple with minimum key"""
            p = self._find_min
            item = self._data.delete(p)
            return (item._key,item._value)
    
    # 已排序列表,插入代价大
    class SortedPriorityQueue(PriorityQueueBase):
        """a min-oriented priority queue implemented with a sorted list"""
        def __init__(self):
            """create a new empty Priority Queue"""
            self._data = PositionalList()
        def __len__(self):
            """return the number of items in the priority queue"""
            return len(self._data)
        def add(self,key,value):
            """add a key-value pair"""
            newest = self._Item(key,value)
            walk = self._data.last()
            # 有序,插入比较麻烦
            while walk is not None and newest < walk.element():
                walk = self._data.before(walk)
            if walk is None:
                self._data.add_first(newest)
            else:
                self._data.add_after(walk,newest)
        def min(self):
            """return but noe remove (k,v) tuple with minimum key"""
            if self.is_empty():
                raise Empty('Priority queue is empty')
            p = self._data.first()
            item = p.element()
            return (item._key,item._value)
        def remove_min(self):
            """return and remove (k,v) with minimum key"""
            if self.is_empty():
                raise Empty('Priority queue is empty')
            item = self._data.delete(self._data.first())
            return (item._key,item._value)
    
    展开全文
  • 最简单的实现一个队列至少满足2个方法,put和get.借助最小堆来实现.这里按"值越大优先级越高"的顺序.#coding=utf-8from heapq import heappush, heappopclass PriorityQueue:def __init__(self):self._queue = []def ...
  • 优先级队列的抽象模型并不把数据存储结构看成是顺序容器。元素在进入优先级队列时,没有任何限制,但在退出时却有一个标准。我们可以把优先级队列想象成数据元素的集合,元素就像被随便丢到垃圾桶一样,彼此没有什么...
  • //缺省的情况下使用小于号,越小的优先级越高 for(int i=0;i;++i){ q.push(arr[i]); } for(int i=n-1;i>=0;--i){ arr[i] = q.top(); q.pop(); } } template void show(T arr[],int n){ for(int i=0;i;++...
  • 排序算法之优先级队列与堆排序

    千次阅读 2018-06-13 16:12:49
      在很多应用中,我们通常需要按照优先级情况对待处理对象进行处理,比如首先处理优先级最高的对象,然后处理次高的对象。最简单的一个例子就是,在手机上玩...这种数据结构就是优先级队列(Priority Queue) 。...
  • Java优先级队列PriorityQueue

    千次阅读 2021-10-29 18:05:16
    相较于普通先进先出队列来说,优先级队列会根据优先级进行由高到低排序,出队时优先级高的先出队。 普通队列对比优先级队列: 1.普通队列: import java.util.LinkedList; import java.util.Queue; public class ...
  • 下面的类利用 heapq 模块实现了一个简单的优先级队列: import heapq class PriorityQueue: def __init__(self): self._queue = [] self._index = 0 def push(self, item, priority): heapq.heappush(self._...
  • 排序利用的数据结构就是一个优先队列。所以这次我们就详述一下用二叉堆来实现一个优先队列。 二叉堆概述 首先我们说一下二叉堆和二叉树的关系。为什么总有人把二叉堆画出二叉树呢? 因为二叉堆其实就是一种特殊的...
  • Java优先级队列(Priority Queue)?

    千次阅读 2018-05-26 17:00:44
    注意:这里的优先级队列不是数据结构中的概念,而是java中的集合类。注意:建议先把我博客里的堆,比较器这两篇文章看一哈优先级队列的定义优先级队列是逻辑结构是小根堆,存储结构是动态数组(到达上限,容量自动...
  • c语言中优先级队列A Priority Queue is a variant of a Queue such that it’s elements are ordered based on their priority. C++ has a built-in priority queue data structure in it’s Standard Template ...
  • 优先级队列PriorityQueue

    2020-08-11 18:04:35
    在小顶堆或是大顶堆堆操作中经常会用到优先级队列PriorityQueue。网上有篇文章讲的不错,转载一波梭哈。 一、什么是优先级队列 1、概念 我们都知道队列,队列的核心思想就是先进先出,这个优先级队列有点不太一样。...
  • 优先级队列 如果我们给每个元素都分配一个数字来标记其优先级,不妨设较小的数字具有较高的优先级,这样我们就可以在一个集合中访问优先级最高的元素并对其进行查找和删除操作了。这样,我们就引入了优先级队列 这种...
  • Java 优先级队列

    2022-02-25 20:54:37
    Java 优先级队列
  • 昨日看了算法导论里讲解的堆排序优先级队列,于是用C语言写了一个优先级队列的简单实现,该实现的最大特点是队列的元素类型是不确定的,可以对任意数据类型进行操作(甚至是自定义的结构体)。这种处理的核心思想是...
  • 39优先级队列中的元素可以按照任意的顺序插入,却总是按照排序的顺序进行检索。无论何时调用remove方法,总会获得当前优先级队列中的最小元素,但并不是对所有元素都排序。它是采用了堆(一个可以自我调整的二叉树),...
  • NULL 博文链接:https://robblog.iteye.com/blog/566114
  • C++ 自定义排序顺序详解,优先级队列 + lambda 表达式
  • 优先级队列

    2020-03-25 15:04:13
    文章目录优先级队列1.优先级队列1.1概念+举例1.2常用接口介绍1.2.1优先级队列的特性1.2.2常用接口1.2.2.1构造方式1.2.2.2常用方法1.2.3.应用2.堆2.1堆的概念:2.2性质:2.3堆和数组的关系2.4向下调整2.5堆的创建2.6...
  • RabbitMQ的优先级队列

    2021-06-25 18:15:21
    优先级队列 队列需要设置优先级队列,消息需要设置消息的优先级。消费者需要等待消息已经发送到队列中,然后对队列中的消息进行排序,最后再去消费。 Map<String, Object> arguments = new HashMap<>()...
  • 数据结构——【优先级队列】详解

    多人点赞 热门讨论 2022-03-09 15:26:18
    目录 一. PriorityQueue PriorityQueue 简介 继承关系 PriorityQueue 示例 ...二....三....四....一....PriorityQueue,即优先级队列优先级队列可以保证每次取出来的元素都是...Java优先级队列默认每次取出来的为最小元素>.
  • 优先级队列的Java实现是一种特殊的队列,其中元素的排序由其自然排序原则确定(默认最小堆),也可以根据创建期间提供的Comparator进行定制。我们在构造过程中调用的构造函数决定要与优先级队列一起使用的排序原则。与...
  • 我们在第四章学习了使用数组实现的队列。...堆排序优先级队列的区别: 下面的例子中,入列的元素大小是无序的,实现的是大顶堆。所以这个优先级队列是按照从大到小次序出列的。下面,我们就用代码实现
  • 1. 优先级队列是什么?? 首先,优先级队列是一个队列,队列所有的性质,它也有。 其次,优先级队列每次取出的是...优先级队列可以对排序对象和比较对象相同的进行排序,也可以对 排序的对象和排序时比较的对象不同 的
  • Java 优先级队列(堆)

    2020-08-11 17:19:01
    Java 优先级队列-堆 二叉树的存储方式存储方式下标关系堆(Heap)概念操作-向下调整操作-建堆堆的应用-优先级队列堆的其他应用 二叉树的存储方式 存储方式 使用数组保存二叉树结构,方式即将二叉树用层序遍历方式放入...
  • js 优先级队列

    2022-04-11 15:23:29
    当我们希望某个优先级权重比较高的数据,展现在最前面,插入数据的时候,应该按照优先级高低来排序,js的优先级队列最为合适。 比如有这样一组数据 校长 院长 老师 学生 他们的权重依次为 0 1 2 3,在乱序的情况下...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 80,001
精华内容 32,000
关键字:

优先级队列排序