Hướng dẫn heapq python max heap - heapq python max heap

Có xây dựng trong đống trong Python, nhưng tôi chỉ muốn chia sẻ điều này nếu có ai muốn tự mình xây dựng nó như tôi. Tôi là người mới ở Python, đừng phán xét nếu tôi đã phạm sai lầm. Thuật toán đang hoạt động nhưng về hiệu quả mà tôi không biết

class Heap :

    def __init__(self):
        self.heap = []
        self.size = 0


    def add(self, heap):
        self.heap = heap
        self.size = len(self.heap)

    def heappush(self, value):
        self.heap.append(value)
        self.size += 1


    def heapify(self, heap ,index=0):

        mid = int(self.size /2)
        """
            if you want to travel great value from bottom to the top you need to repeat swaping by the hight of the tree
            I  don't how how can i get the  height of the tree that's why i use sezi/2
            you can find height by this formula
            2^(x) = size+1  why 2^x because tree is growing exponentially 
            xln(2) = ln(size+1)
            x = ln(size+1)/ln(2)
        """

        for i in range(mid):
            self.createTee(heap ,index)

        return heap

    def createTee(self,  heap ,shiftindex):

        """
        """
        """

            this pos reffer to the index of the parent only parent with children
                    (1)
                (2)      (3)           here the size of list is 7/2 = 3
            (4)   (5)  (6)  (7)        the number of parent is 3 but we use {2,1,0} in while loop
                                       that why a put pos -1

        """
        pos = int(self.size /2 ) -1
        """
            this if you wanna sort this heap list we should swap max value in the root of the tree with the last
            value in the list and if you wanna repeat this until sort all list you will need to prevent the func from
            change what we already sorted I should decrease the size of the list that will heapify on it

        """

        newsize = self.size - shiftindex
        while pos >= 0 :
            left_child = pos * 2 + 1
            right_child = pos * 2 + 2
            # this mean that left child is exist
            if left_child < newsize:
                if right_child < newsize:
                    # if the right child exit we wanna check if left child > rightchild
                    # if right child doesn't exist we can check that we will get error out of range
                    if heap[pos] < heap[left_child] and heap[left_child]  > heap[right_child] :
                        heap[left_child] , heap[pos] = heap[pos], heap[left_child]
                # here if the righ child doesn't exist
                else:
                    if heap[pos] < heap[left_child] :
                        heap[left_child] , heap[pos] = heap[pos], heap[left_child]
            # if the right child exist
            if right_child < newsize :
                if heap[pos] < heap[right_child] :
                    heap[right_child], heap[pos] = heap[pos], heap[right_child]
            pos -= 1

        return heap

    def sort(self ):
        k = 1
        for i in range(self.size -1 ,0 ,-1):
            """
            because this is max heap we swap root with last element in the list

            """
            self.heap [0] , self.heap[i] = self.heap[i], self.heap[0]
            self.heapify(self.heap ,k)
            k+=1

        return self.heap


h = Heap()
h.add([5,7,0,8,9,10,20,30,50,-1] )
h.heappush(-2)
print(" before heapify ")
print(h.heap)
print(" after heapify ")
print(h.heapify(h.heap,0))
print(" after sort ")
print(h.sort())

Đầu ra:

Trước khi Heapify [5, 7, 0, 8, 9, 10, 20, 30, 50, -1, -2]

Sau khi Heapify [50, 30, 20, 8, 9, 10, 0, 7, 5, -1, -2]

Sau khi sắp xếp [-2, -1, 0, 5, 7, 8, 9, 10, 20, 30, 50]

Tôi hy vọng bạn hiểu mã của tôi. Nếu có điều gì đó bạn không hiểu, hãy bình luận, tôi sẽ cố gắng giúp đỡ

Mã nguồn: lib/heapq.py 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à

>>> 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]
7 và
>>> 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]
8 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,
>>> 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]
9.

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ờ:

>>> 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]
9 là mục nhỏ nhất và

>>> 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]
0 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

>>> 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]
1 hoặc bạn có thể chuyển đổi danh sách dân cư thành một đống thông qua hàm
>>> 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]
2.

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

________ 13 ________ 14 (heap, mặt hàng) ¶(heap, item)¶(heap, item)

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

________ 13 ________ 16 (Heap) ¶(heap)¶(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,

>>> 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]
7 đượ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
>>> 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]
9. ________ 13 ________ 20 (heap, mặt hàng) ¶(heap, item)¶(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')
1, 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')
2. ________ 13 ________ 24 (x)(x)¶(x)

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

________ 13 ________ 26 (heap, mặt hàng) ¶(heap, item)¶(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,

>>> 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]
7 đượ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')
2 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')
1 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 đó là mong muốn, hãy xem xét sử dụng

>>> 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]
00 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.

________ 13 ________ 32 (*iterables, key = none, lùi = sai) ¶(*iterables, key=None, reverse=False)¶(*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.iterator over the sorted values.

Tương tự như

>>> 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]
03 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à

>>> 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]
04 (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
>>> 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]
04 (compare the elements directly).key function of one argument that is used to extract a comparison key from each input element. The default value is
>>> 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]
04 (compare the elements directly).

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

>>> 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]
05, 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ư
>>> 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]
06, 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.Added the optional key and reverse parameters.

________ 13 ________ 38 (n, có thể lặp lại, khóa = không) ¶(n, iterable, key=None)¶(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ụ:

>>> 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]
09). Tương đương với:
>>> 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]
70. ________ 13 ________ 42 (n, có thể lặp lại, khóa = không) ¶(n, iterable, key=None)¶(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ụ:

>>> 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]
09). Tương đương với:
>>> 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]
74.

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

>>> 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]
75 hiệu quả hơn. Ngoài ra, khi
>>> 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]
76, việc sử dụng các hàm
>>> 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]
77 và
>>> 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]
78 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ư

>>> 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]
79, nhưng không giống như
>>> 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]
75, 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:

>>> 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]
0

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:

>>> 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]
7

Học thuyết¶

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

>>> 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]
01 và
>>> 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]
02 cho tất cả các phần tử K, đếm các yếu tố từ 0. Vì mục đí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à
>>> 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]
03 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

>>> 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]
04:
>>> 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]
0

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

>>> 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]
05 và
>>> 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]
06. 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! :-)