Hướng dẫn python heap priority queue implementation - Triển khai hàng đợi ưu tiên trong python heap

Mã nguồn: lib/heapq.py Lib/heapq.py


Mô -đun này cung cấp việc triển khai thuật toán hàng đợi Heap, còn được gọi là thuật toán hàng đợi ưu tiên.

Thoát nước là những cây nhị phân mà mọi nút cha mẹ đều có giá trị nhỏ hơn hoặc bằng với bất kỳ con nào của nó. Việc triển khai này sử dụng các mảng mà heap[k] <= heap[2*k+1]heap[k] <= heap[2*k+2] cho tất cả K, đếm các phần tử từ số 0. Để so sánh, các yếu tố không tồn tại được coi là vô hạn. Thuộc tính thú vị của một đống là phần tử nhỏ nhất của nó luôn là gốc, heap[0].

API bên dưới khác với các thuật toán Heap Sách giáo khoa trong hai khía cạnh: (a) Chúng tôi sử dụng lập chỉ mục dựa trên không. Điều này làm cho mối quan hệ giữa chỉ mục cho một nút và các chỉ mục cho con cái hơi ít rõ ràng hơn, nhưng phù hợp hơn vì Python sử dụng lập chỉ mục dựa trên không. .

Hai người này có thể xem Heap như một danh sách Python thông thường mà không có bất ngờ: heap[0] là mặt hàng nhỏ nhất và heap.sort() duy trì bất biến Heap!

Để tạo một đống, hãy sử dụng danh sách được khởi tạo thành

>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')
0 hoặc bạn có thể chuyển đổi danh sách dân cư thành một đống thông qua chức năng
>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')
1.

Các chức năng sau được cung cấp:

Heapq.HeAppush (Heap, Item) ¶heappush(heap, item)

Đẩy mặt hàng giá trị lên đống, duy trì heap bất biến.

Heapq.HeAppop (Heap) ¶heappop(heap)

Pop và trả lại vật phẩm nhỏ nhất từ ​​đống, duy trì bất biến. Nếu đống trống,

>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')
2 được nâng lên. Để truy cập mục nhỏ nhất mà không cần bật nó, hãy sử dụng heap[0].

Heapq.HeAppushpop (Heap, Item) ¶heappushpop(heap, item)

Đẩy vật phẩm lên đống, sau đó bật và trả lại vật phẩm nhỏ nhất từ ​​đống. Hành động kết hợp chạy hiệu quả hơn

>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')
4, sau đó là một cuộc gọi riêng đến
>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')
5.

Heapq.Heapify (x) ¶heapify(x)

Biến đổi danh sách X thành một đống, tại chỗ, trong thời gian tuyến tính.

Heapq.Heapreplace (Heap, Item) ¶heapreplace(heap, item)

Pop và trả lại các mặt hàng nhỏ nhất từ ​​đống, và cũng đẩy mục mới. Kích thước đống không thay đổi. Nếu đống trống,

>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')
2 được nâng lên.

Hoạt động một bước này hiệu quả hơn so với

>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')
5 sau đó là
>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')
4 và có thể phù hợp hơn khi sử dụng một đống kích thước cố định. Sự kết hợp pop/push luôn trả về một phần tử từ đống và thay thế nó bằng vật phẩm.

Giá trị được trả về có thể lớn hơn mục được thêm vào. Nếu đó không phải là mong muốn, hãy xem xét sử dụng

>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')
9 thay thế. Sự kết hợp đẩy/pop của nó trả về các giá trị nhỏ hơn của hai giá trị, để lại giá trị lớn hơn trên đống.

Mô -đun cũng cung cấp ba chức năng mục đích chung dựa trên đống.

heapq.merge (*iterables, key = none, lùi = sai) ¶merge(*iterables, key=None, reverse=False)

Hợp nhất nhiều đầu vào được sắp xếp vào một đầu ra được sắp xếp duy nhất (ví dụ: hợp nhất các mục nhập thời gian từ nhiều tệp nhật ký). Trả về một trình lặp qua các giá trị được sắp xếp.iterator over the sorted values.

Tương tự như

from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
0 nhưng trả về một điều khác, không kéo dữ liệu vào bộ nhớ cùng một lúc và giả sử rằng mỗi luồng đầu vào đã được sắp xếp (nhỏ nhất đến lớn nhất).

Có hai đối số tùy chọn phải được chỉ định là đối số từ khóa.

Khóa chỉ định chức năng chính của một đối số được sử dụng để trích xuất một khóa so sánh từ mỗi phần tử đầu vào. Giá trị mặc định là

from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
1 (so sánh trực tiếp các phần tử).key function of one argument that is used to extract a comparison key from each input element. The default value is
from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
1 (compare the elements directly).

Đảo ngược là một giá trị boolean. Nếu được đặt thành

from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
2, thì các phần tử đầu vào được hợp nhất như thể mỗi so sánh được đảo ngược. Để đạt được hành vi tương tự như
from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
3, tất cả các vòng lặp phải được sắp xếp từ lớn nhất đến nhỏ nhất.

Đã thay đổi trong phiên bản 3.5: Đã thêm các tham số khóa và đảo ngược tùy chọn.Added the optional key and reverse parameters.

heapq.nlargest (n, itable, key = none) ¶nlargest(n, iterable, key=None)

Trả về một danh sách với các phần tử lớn nhất từ ​​bộ dữ liệu được xác định bởi ITable. Khóa, nếu được cung cấp, chỉ định hàm của một đối số được sử dụng để trích xuất một khóa so sánh từ mỗi phần tử trong ITable (ví dụ:

from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
4). Tương đương với:
from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
5.

heapq.nsmallest (n, itable, key = none) ¶nsmallest(n, iterable, key=None)

Trả về một danh sách với n phần tử nhỏ nhất từ ​​bộ dữ liệu được xác định bởi ITable. Khóa, nếu được cung cấp, chỉ định hàm của một đối số được sử dụng để trích xuất một khóa so sánh từ mỗi phần tử trong ITable (ví dụ:

from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
4). Tương đương với:
from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
7.

Hai hàm sau hoạt động tốt nhất cho các giá trị nhỏ hơn của n. Đối với các giá trị lớn hơn, việc sử dụng hàm

from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
8 hiệu quả hơn. Ngoài ra, khi
from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
9, việc sử dụng các hàm
pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count()     # unique sequence count

def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush(pq, entry)

def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED

def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')
0 và
pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count()     # unique sequence count

def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush(pq, entry)

def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED

def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')
1 tích hợp sẽ hiệu quả hơn. Nếu việc sử dụng lặp đi lặp lại của các chức năng này là bắt buộc, hãy xem xét việc biến số thứ có thể lặp lại thành một đống thực tế.

Ví dụ cơ bản

Một Heapsort có thể được thực hiện bằng cách đẩy tất cả các giá trị lên một đống và sau đó bật ra các giá trị nhỏ nhất cùng một lúc:

>>> def heapsort(iterable):
...     h = []
...     for value in iterable:
...         heappush(h, value)
...     return [heappop(h) for i in range(len(h))]
...
>>> heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Điều này tương tự như

pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count()     # unique sequence count

def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush(pq, entry)

def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED

def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')
2, nhưng không giống như
from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
8, việc triển khai này không ổn định.

Các yếu tố đống có thể là bộ dữ liệu. Điều này rất hữu ích để gán các giá trị so sánh (như ưu tiên nhiệm vụ) cùng với bản ghi chính được theo dõi:

>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')

Ghi chú triển khai hàng đợi ưu tiên

Hàng đợi ưu tiên là sử dụng phổ biến cho một đống và nó đưa ra một số thách thức thực hiện:

  • Sắp xếp sự ổn định: Làm thế nào để bạn nhận được hai nhiệm vụ với các ưu tiên bằng nhau được trả lại theo thứ tự ban đầu chúng được thêm vào?

  • So sánh Tuple phá vỡ các cặp (ưu tiên, nhiệm vụ) nếu các ưu tiên bằng nhau và các tác vụ không có thứ tự so sánh mặc định.

  • Nếu mức độ ưu tiên của một tác vụ thay đổi, làm thế nào để bạn di chuyển nó đến một vị trí mới trong đống?

  • Hoặc nếu một nhiệm vụ đang chờ xử lý cần phải bị xóa, làm thế nào để bạn tìm thấy nó và loại bỏ nó khỏi hàng đợi?

Một giải pháp cho hai thử thách đầu tiên là lưu trữ các mục dưới dạng danh sách 3 phần tử bao gồm ưu tiên, số lượng nhập cảnh và nhiệm vụ. Số lượng mục nhập đóng vai trò là một công cụ phá vỡ để hai nhiệm vụ có cùng mức độ ưu tiên được trả về theo thứ tự chúng được thêm vào. Và vì không có hai số nhập nào là giống nhau, so sánh tuple sẽ không bao giờ cố gắng so sánh trực tiếp hai nhiệm vụ.

Một giải pháp khác cho vấn đề của các tác vụ không thể so sánh là tạo ra một lớp trình bao bọc bỏ qua mục nhiệm vụ và chỉ so sánh trường ưu tiên:

from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)

Các thách thức còn lại xoay quanh việc tìm kiếm một nhiệm vụ đang chờ xử lý và thực hiện các thay đổi đối với mức độ ưu tiên của nó hoặc loại bỏ nó hoàn toàn. Tìm một nhiệm vụ có thể được thực hiện với một từ điển chỉ vào một mục trong hàng đợi.

Việc loại bỏ mục nhập hoặc thay đổi mức độ ưu tiên của nó khó khăn hơn vì nó sẽ phá vỡ cấu trúc đống bất biến. Vì vậy, một giải pháp khả thi là đánh dấu mục nhập được xóa và thêm một mục mới với mức độ ưu tiên sửa đổi:

pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count()     # unique sequence count

def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush(pq, entry)

def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED

def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')

Học thuyết¶

Các đống là các mảng mà

pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count()     # unique sequence count

def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush(pq, entry)

def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED

def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')
4 và
pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count()     # unique sequence count

def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush(pq, entry)

def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED

def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')
5 Đối với tất cả các phần tử K, đếm từ 0. Vì lợi ích so sánh, các yếu tố không tồn tại được coi là vô hạn. Tài sản thú vị của một đống là
pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count()     # unique sequence count

def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush(pq, entry)

def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED

def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')
6 luôn là yếu tố nhỏ nhất của nó.

Các bất biến kỳ lạ ở trên có nghĩa là một đại diện bộ nhớ hiệu quả cho một giải đấu. Các số dưới đây là K, không phải

pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count()     # unique sequence count

def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush(pq, entry)

def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED

def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')
7:

                               0

              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

Trong cây trên, mỗi ô K đang đứng đầu

pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count()     # unique sequence count

def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush(pq, entry)

def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED

def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')
8 và
pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count()     # unique sequence count

def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush(pq, entry)

def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED

def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')
9. Trong một giải đấu nhị phân thông thường mà chúng ta thấy trong thể thao, mỗi tế bào là người chiến thắng trên hai tế bào mà nó đứng đầu, và chúng ta có thể theo dõi người chiến thắng xuống cây để thấy tất cả các đối thủ. Tuy nhiên, trong nhiều ứng dụng máy tính của các giải đấu như vậy, chúng tôi không cần phải theo dõi lịch sử của người chiến thắng. Để hiệu quả hơn về bộ nhớ, khi một người chiến thắng được thăng chức, chúng tôi cố gắng thay thế nó bằng một thứ khác ở cấp độ thấp hơn và quy tắc trở thành một tế bào và hai ô mà nó đứng đầu chứa ba mục khác nhau, nhưng ô trên cùng có chiến thắng trên hai tế bào đứng đầu.

Nếu bất biến Heap này được bảo vệ mọi lúc, chỉ số 0 rõ ràng là người chiến thắng chung cuộc. Cách thuật toán đơn giản nhất để loại bỏ nó và tìm ra người chiến thắng tiếp theo là di chuyển một số kẻ thua cuộc (hãy nói ô 30 trong sơ đồ ở trên) vào vị trí 0, sau đó đưa ra cái 0 mới này xuống cây, trao đổi giá trị, cho đến khi bất biến được thiết lập lại. Đây rõ ràng là logarit trên tổng số mặt hàng trong cây. Bằng cách lặp lại trên tất cả các mục, bạn sẽ có một loại O (n log n).

Một tính năng hay của loại này là bạn có thể chèn hiệu quả các mục mới trong khi loại đang diễn ra, với điều kiện là các mục được chèn không phải là tốt hơn so với phần tử 0 cuối cùng mà bạn trích xuất. Điều này đặc biệt hữu ích trong bối cảnh mô phỏng, trong đó cây tổ chức tất cả các sự kiện đến và điều kiện của Win Win có nghĩa là thời gian dự kiến ​​nhỏ nhất. Khi một sự kiện lên lịch các sự kiện khác để thực hiện, chúng được lên lịch trong tương lai, vì vậy chúng có thể dễ dàng đi vào đống. Vì vậy, một đống là một cấu trúc tốt để triển khai các bộ lập lịch (đây là những gì tôi đã sử dụng cho trình tự MIDI của mình :-).

Các cấu trúc khác nhau để thực hiện lập lịch trình đã được nghiên cứu rộng rãi và đống rất tốt cho việc này, vì chúng rất nhanh, tốc độ gần như không đổi và trường hợp xấu nhất không khác nhiều so với trường hợp trung bình. Tuy nhiên, có những đại diện khác hiệu quả hơn, nhưng những trường hợp tồi tệ nhất có thể là khủng khiếp.

Thoát cũng rất hữu ích trong các loại đĩa lớn. Tất cả có lẽ tất cả các bạn đều biết rằng một loại lớn ngụ ý việc sản xuất các lần chạy trên mạng (là các chuỗi được sắp xếp trước, có kích thước thường liên quan đến lượng bộ nhớ CPU), theo sau là một đường đi hợp nhất cho các lần chạy này, việc hợp nhất thường rất thông minh Có tổ chức 1. Điều rất quan trọng là loại ban đầu tạo ra các lần chạy dài nhất có thể. Giải đấu là một cách tốt để đạt được điều đó. Nếu, sử dụng tất cả bộ nhớ có sẵn để tổ chức một giải đấu, bạn thay thế và các vật phẩm có thể xảy ra để phù hợp với hoạt động hiện tại, bạn sẽ tạo ra các lần chạy gấp đôi số lượng của bộ nhớ cho đầu vào ngẫu nhiên và tốt hơn nhiều cho đầu vào được đặt hàng.

Hơn nữa, nếu bạn xuất ra mục 0'th trên đĩa và nhận đầu vào có thể không phù hợp với giải đấu hiện tại (vì giá trị là chiến thắng trên giá trị đầu ra cuối cùng), nó không thể phù hợp với heap, vì vậy kích thước của HEAP giảm. Bộ nhớ được giải phóng có thể được sử dụng lại một cách khéo léo ngay lập tức để xây dựng một đống thứ hai, phát triển với cùng một tốc độ mà đống đầu tiên đang tan chảy. Khi đống đầu tiên biến mất hoàn toàn, bạn chuyển đổi đống và bắt đầu chạy mới. Thông minh và khá hiệu quả!

Trong một từ, đống là cấu trúc bộ nhớ hữu ích cần biết. Tôi sử dụng chúng trong một vài ứng dụng và tôi nghĩ thật tốt khi giữ một mô -đun ‘heap. :-)

Chú thích

1

Các thuật toán cân bằng đĩa có hiện tại, ngày nay, khó chịu hơn thông minh, và đây là hậu quả của khả năng tìm kiếm của các đĩa. Trên các thiết bị không thể tìm kiếm, như ổ đĩa băng lớn, câu chuyện khá khác nhau và người ta phải rất thông minh để đảm bảo (trước) rằng mỗi chuyển động băng sẽ có hiệu quả nhất có thể (đó là sẽ tham gia tốt nhất tại tiến triển của sự hợp nhất). Một số băng thậm chí có thể đọc ngược, và điều này cũng được sử dụng để tránh thời gian tua lại. Hãy tin tôi, các loại băng thực sự tốt là khá ngoạn mục để xem! Từ mọi thời đại, việc sắp xếp luôn là một nghệ thuật tuyệt vời! :-)

HEAP có thể được sử dụng để thực hiện hàng đợi ưu tiên không?

Chúng ta có thể sử dụng đống để thực hiện hàng đợi ưu tiên. Nó sẽ mất thời gian O (log n) để chèn và xóa từng phần tử trong hàng đợi ưu tiên. Dựa trên cấu trúc heap, hàng đợi ưu tiên cũng có hai loại hàng đợi ưu tiên tối đa và hàng đợi ưu tiên.. It will take O(log N) time to insert and delete each element in the priority queue. Based on heap structure, priority queue also has two types max- priority queue and min - priority queue.

Python có phải là hàng đợi ưu tiên không?

Hàng đợi ưu tiên là một cấu trúc dữ liệu tương tự như hàng đợi thông thường hoặc ngăn xếp, nhưng mỗi phần tử có mức độ ưu tiên liên quan. Các yếu tố có ưu tiên cao được phục vụ trước các yếu tố ưu tiên thấp hơn. Hàng đợi ưu tiên thường được triển khai bằng cấu trúc dữ liệu HEAP.Priority queues are typically implemented using a heap data structure.

Làm thế nào là một hàng đợi ưu tiên được thực hiện trong Python?

Python giải quyết điều này bằng cách sử dụng một đống nhị phân để thực hiện hàng đợi ưu tiên.Hàng đợi ưu tiên Python được xây dựng trên mô -đun FEAPQ, về cơ bản là một đống nhị phân.Lệnh nhận được các yếu tố ưu tiên cao nhất từ hàng đợi.Các cặp đối tượng ưu tiên cũng có thể được chèn vào hàng đợi.using a binary heap to implement the priority queue. The Python priority queue is built on the heapq module, which is basically a binary heap. The get command dequeues the highest priority elements from the queue. Priority-object pairs can also be inserted into the queue.

Làm cách nào để sử dụng Heap làm hàng đợi ưu tiên?

Chèn một phần tử vào hàng đợi ưu tiên (tối đa-heap) được thực hiện bằng các bước sau ...
Chèn phần tử mới ở cuối cây.Chèn một phần tử ở cuối hàng đợi ..
HEAPIDE Cây.Heapify sau khi chèn ..