Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python优先级队列Heapify方法_Python_Heap_Priority Queue - Fatal编程技术网

Python优先级队列Heapify方法

Python优先级队列Heapify方法,python,heap,priority-queue,Python,Heap,Priority Queue,我将此库用于堆: from Queue import PriorityQueue 我需要触发heapify,因为在此优先级队列中我插入了一个节点类,并且优先级队列是基于node.val排序的,如下所示: class Node(): __init__(self,val,text): self.val = val self.text = text first.val = 100 我的pq: pq = PriorityQueue() first = Node(

我将此库用于堆:

from Queue import PriorityQueue
我需要触发heapify,因为在此优先级队列中我插入了一个节点类,并且优先级队列是基于node.val排序的,如下所示:

class Node():
   __init__(self,val,text):
       self.val = val
       self.text = text

first.val = 100
我的pq:

pq = PriorityQueue()
first = Node(1,'abcd')
pq.put((first.val,first))

xyz = Node(10,'asdf')
pq.put((xyz.val,xyz))


fsa = Node(7,'asdsbcd')
pq.put((fsa.val,fsa))

现在它可以正常工作,但如果我想更改first nodes值,例如:

class Node():
   __init__(self,val,text):
       self.val = val
       self.text = text

first.val = 100
有没有像pq.heapify()之类的方法


如何调用heapify方法以便它可以对其进行排序?因为如果我不这样做,那么它将对列表进行排序,并假设first仍然是1而不是100。

我相信它最好用于堆

然后,您可以使用来自的进程更新堆中的最小值,如下所示

优势:

  • 该方法允许使用replace更新最小的元素
  • 只需O(log(n))即可更新最小元素的值(即首先从1更改为100)
  • 当只需要更新一个项目时(需要O(n))比使用Heapify更快
  • 代码

    import heapq
    
    class Node():
      def __init__(self,val,text):
           self.val = val 
           self.text = text
      def __str__(self):   # Add a method to node to string for display
        return f'{self.val}, {self.text}'
    
    class MyHeap(object):
      """The class keeps an internal list, where each element is a tuple.
        The first tuple element is the priority (val), calculated at element insertion 
        time, using the key parameter, passed at Heap instantiation"""
      def __init__(self, initial=None, key=lambda x:x.val):
        self.key = key
        if initial:
          self._data = [(key(item), item) for item in initial]
          heapq.heapify(self._data)
        else:
          self._data = []
    
      def push(self, item):
        heapq.heappush(self._data, (self.key(item), item))
    
      def pop(self):
        return heapq.heappop(self._data)[1]
    
      def replace(self, item):
        # Pops min element and adds a new element
        v = self.pop()
        self.push(item)
        return v
    
    测试

    测试1。添加元素并转储堆

    # Add elements
    pq = MyHeap()
    first = Node(1,'abcd')
    pq.push(first)
    
    xyz = Node(10,'asdf')
    pq.push(xyz)
    
    fsa = Node(7,'asdsbcd')
    pq.push(fsa)
    
    # Dump elements in order
    print('Initial Ordering')
    while pq._data:
      print(pq.pop())
    
    结果

    测试2。删除最小值,并添加为具有较大值的新元素

    # Add elements
    pq.push(first)
    pq.push(xyz)
    pq.push(fsa)
    
    # Update first element using replace
    first.val = 100
    pq.replace(first)
    
    print('\nNew Ordering')
    while pq._data:
      print(pq.pop())
    
    结果

    测试3:将元素添加为列表

    结果


    标准堆类通常只有插入、顶部查找和顶部删除的方法,即不允许修改内部数据结构。您需要实现自己的优先级queue@mangusta嗯,移除某个节点怎么样?有办法吗?这样我就可以删除它,然后用我脑海中出现的更新的val.重新插入它,但我不确定python中是否有这样的方法。Java的优先级队列有一个方法
    remove(objecto)
    ,我不确定这个库是否可以做到这一点。但是,考虑HEAPQ库Python提供的HeAPIZEP方法:因为它看起来快,所以会接受URL,但是我做了一些不同的事情,更容易对THO进行编码——我刚刚删除了整个堆并把它放在一个数组中,然后重新生成堆,确保更新了新值。@asdadasd--问题是修改元素的方式需要O(n)时间(即,因为Heapify是O(n))。使用此处建议的方法执行更新需要O(log(n))这要快得多。对于n~10^6,上面的方法是~20,而使用Heapify~O(n^6),速度慢50,00倍。但是,如果你不经常这样做,或者元素的数量很小,那就没关系了。是的,但我不在leetcode上-学校作业-所以对我来说少编码更好。@asdadasd--“简单比复杂好”。因此,如果您的技术有效并且代码更简单,那么是的,最好使用它。只有更复杂的问题才需要更复杂的代码。
    print('\nUsing List')
    pq = MyHeap([first, xyz, fsa])
    while pq._data:
      print(pq.pop())
    
    Using List
    7, asdsbcd
    10, asdf
    100, abcd