Cây tìm kiếm Heap vs Binary (BST)


169

Sự khác biệt giữa một đống và BST là gì?

Khi nào nên sử dụng một đống và khi nào sử dụng BST?

Nếu bạn muốn có được các yếu tố theo cách sắp xếp, BST có tốt hơn heap không?


13
Câu hỏi này dường như lạc đề vì nó liên quan đến khoa học máy tính và nên được hỏi trên cs.stackexchange.com
Flow

3
@Flow nó đã được yêu cầu có tại địa chỉ: cs.stackexchange.com/questions/27860/...
Ciro Santilli郝海东冠状病六四事件法轮功

3
Tôi cảm thấy như nó liên quan đến cả trao đổi ngăn xếp và tràn ngăn xếp. Vì vậy, có nó ở đây là tốt
Azizbro

Câu trả lời:


190

Tóm lược

          Type      BST (*)   Heap
Insert    average   log(n)    1
Insert    worst     log(n)    log(n) or n (***)
Find any  worst     log(n)    n
Find max  worst     1 (**)    1
Create    worst     n log(n)  n
Delete    worst     log(n)    log(n)

Tất cả thời gian trung bình trên bảng này giống như thời gian tồi tệ nhất của chúng ngoại trừ Chèn.

  • *: ở mọi nơi trong câu trả lời này, BST == BST cân bằng, vì không cân bằng hút không có triệu chứng
  • **: sử dụng một sửa đổi tầm thường được giải thích trong câu trả lời này
  • ***: log(n)cho heap cây con trỏ, ncho heap mảng động

Ưu điểm của đống nhị phân so với BST

  • thời gian trung bình chèn vào một đống nhị phân là O(1), đối với BST là O(log(n)). Đây là tính năng sát thủ của đống.

    Ngoài ra còn có các đống khác đạt được O(1)khấu hao (mạnh hơn) như Heap Fibros , và thậm chí trường hợp xấu nhất, như hàng đợi Brodal , mặc dù chúng có thể không thực tế vì hiệu suất không có triệu chứng: Các đống Fibonacci hoặc hàng đợi Brodal được sử dụng trong thực tế ở bất cứ đâu?

  • đống nhị phân có thể được thực hiện một cách hiệu quả trên đỉnh của các mảng động hoặc cây dựa trên con trỏ, cây chỉ dựa trên BST. Vì vậy, đối với heap, chúng ta có thể chọn triển khai mảng hiệu quả hơn về không gian, nếu chúng ta có thể đủ khả năng thay đổi kích thước thời gian trễ.

  • tạo heap nhị phân O(n)trường hợp xấu nhất , O(n log(n))đối với BST.

Lợi thế của BST so với đống nhị phân

  • tìm kiếm các yếu tố tùy ý là O(log(n)). Đây là tính năng sát thủ của BST.

    Đối với heap, nó O(n)nói chung, ngoại trừ phần tử lớn nhất O(1).

Lợi thế "sai" của heap so với BST

  • Heap là O(1)để tìm max, BST O(log(n)).

    Đây là một quan niệm sai lầm phổ biến, bởi vì việc sửa đổi BST để theo dõi phần tử lớn nhất và cập nhật nó bất cứ khi nào phần tử đó có thể thay đổi: khi chèn một hoán đổi lớn hơn, khi loại bỏ tìm phần lớn thứ hai. Chúng ta có thể sử dụng cây tìm kiếm nhị phân để mô phỏng hoạt động heap không? (được đề cập bởi Yeo ).

    Trên thực tế, đây là một hạn chế của đống so với các BST: tìm kiếm hiệu quả duy nhất là cho phần tử lớn nhất.

Chèn heap nhị phân trung bình là O(1)

Nguồn:

Lập luận trực quan:

  • cấp độ cây dưới cùng có nhiều yếu tố theo cấp số nhân hơn cấp độ cao nhất, vì vậy các yếu tố mới gần như chắc chắn sẽ đi ở phía dưới
  • chèn heap bắt đầu từ dưới cùng , BST phải bắt đầu từ đầu

Trong một đống nhị phân, tăng giá trị tại một chỉ mục nhất định cũng O(1)vì lý do tương tự. Nhưng nếu bạn muốn làm điều đó, có khả năng bạn sẽ muốn cập nhật một chỉ mục bổ sung cho các hoạt động heap Làm thế nào để thực hiện thao tác giảm phím O (logn) cho Hàng đợi ưu tiên dựa trên heap? ví dụ cho Dijkstra. Có thể không có chi phí thêm thời gian.

Thư viện chuẩn GCC C ++ chèn điểm chuẩn trên phần cứng thực

Tôi đã điểm chuẩn C ++ std::set( BST cây đen đỏ ) và chèn std::priority_queue( heap mảng động ) để xem liệu tôi có đúng về thời gian chèn hay không và đây là những gì tôi nhận được:

nhập mô tả hình ảnh ở đây

  • mã điểm chuẩn
  • kịch bản cốt truyện
  • dữ liệu cốt truyện
  • đã thử nghiệm trên Ubuntu 19.04, GCC 8.3.0 trên máy tính xách tay Lenovo ThinkPad P51 với CPU: CPU Intel Core i7-7820HQ (4 lõi / 8 luồng, cơ sở 2,90 GHz, bộ nhớ cache 8 MB), RAM: 2x Samsung M471A2K43BB1-CRC (2x 16GiB , 2400 Mbps), SSD: Samsung MZVLB512HAJQ-000L7 (512GB, 3.000 MB / s)

Vì vậy, rõ ràng:

  • thời gian chèn heap về cơ bản là không đổi.

    Chúng ta có thể thấy rõ các điểm thay đổi kích thước mảng động. Vì chúng tôi đang tính trung bình cứ sau 10k chèn để có thể nhìn thấy mọi thứ ở mức nhiễu trên hệ thống , nên các đỉnh đó thực tế lớn hơn khoảng 10 nghìn lần so với hiển thị!

    Biểu đồ thu phóng loại trừ về cơ bản chỉ các điểm thay đổi kích thước mảng và cho thấy hầu hết tất cả các phần chèn đều nằm dưới 25 nano giây.

  • BST là logarit. Tất cả các chèn đều chậm hơn nhiều so với chèn heap trung bình.

  • Phân tích chi tiết BST vs hashmap tại: Cấu trúc dữ liệu nào bên trong std :: map trong C ++?

Thư viện chuẩn GCC C ++ chèn điểm chuẩn trên gem5

gem5 là một trình giả lập hệ thống đầy đủ, và do đó cung cấp một đồng hồ chính xác vô cùng với m5 dumpstats. Vì vậy, tôi đã cố gắng sử dụng nó để ước tính thời gian cho các lần chèn riêng lẻ.

nhập mô tả hình ảnh ở đây

Diễn dịch:

  • Heap vẫn không đổi, nhưng bây giờ chúng ta thấy chi tiết hơn rằng có một vài dòng, và mỗi dòng cao hơn thì thưa thớt hơn.

    Điều này phải tương ứng với độ trễ truy cập bộ nhớ được thực hiện cho các chèn cao hơn và cao hơn.

  • TODO Tôi thực sự không thể diễn giải BST đầy đủ vì nó trông không quá logarit và có phần bất biến hơn.

    Tuy nhiên, với chi tiết lớn hơn này, chúng ta có thể thấy cũng có thể thấy một vài dòng riêng biệt, nhưng tôi không chắc chúng đại diện cho cái gì: Tôi có thể mong đợi dòng dưới cùng mỏng hơn, vì chúng ta chèn dưới cùng?

Điểm chuẩn với thiết lập Buildroot này trên CPU aarch64 HPI .

BST không thể được thực hiện hiệu quả trên một mảng

Hoạt động heap chỉ cần bong bóng lên hoặc xuống một nhánh cây, vì vậy O(log(n))trường hợp xấu nhất là hoán đổi, O(1)trung bình.

Giữ BST cân bằng đòi hỏi phải xoay cây, có thể thay đổi phần tử trên cùng cho phần tử khác và sẽ yêu cầu di chuyển toàn bộ mảng xung quanh ( O(n)).

Heaps có thể được thực hiện hiệu quả trên một mảng

Chỉ số phụ huynh và trẻ em có thể được tính toán từ chỉ số hiện tại như được hiển thị ở đây .

Không có hoạt động cân bằng như BST.

Xóa min là thao tác đáng lo ngại nhất vì nó phải từ trên xuống. Nhưng nó luôn có thể được thực hiện bằng cách "tô màu xuống" một nhánh của đống như được giải thích ở đây . Điều này dẫn đến trường hợp xấu nhất O (log (n)), vì heap luôn được cân bằng tốt.

Nếu bạn đang chèn một nút duy nhất cho mỗi nút bạn xóa, thì bạn sẽ mất lợi thế của chèn trung bình O (1) không có triệu chứng mà heaps cung cấp khi việc xóa sẽ chiếm ưu thế và bạn cũng có thể sử dụng BST. Tuy nhiên, Dijkstra cập nhật các nút nhiều lần cho mỗi lần xóa, vì vậy chúng tôi vẫn ổn.

Heap mảng động so với đống cây con trỏ

Heaps có thể được thực hiện một cách hiệu quả trên đỉnh heap con trỏ: Có thể thực hiện heap nhị phân dựa trên con trỏ hiệu quả không?

Việc thực hiện mảng động là không gian hiệu quả hơn. Giả sử rằng mỗi phần tử heap chỉ chứa một con trỏ tới struct:

  • việc thực hiện cây phải lưu trữ ba con trỏ cho mỗi phần tử: cha mẹ, con trái và con phải. Vì vậy, việc sử dụng bộ nhớ luôn luôn 4n(3 con trỏ cây + 1 structcon trỏ).

    Các BST cây cũng sẽ cần thêm thông tin cân bằng, ví dụ như màu đen-đỏ.

  • việc thực hiện mảng động có thể có kích thước 2nchỉ sau khi nhân đôi. Vì vậy, trung bình nó sẽ được 1.5n.

Mặt khác, heap cây có chèn trường hợp xấu nhất tốt hơn, bởi vì sao chép mảng động sao lưu để tăng gấp đôi kích thước của nó thì O(n)trường hợp xấu nhất, trong khi đó, heap cây chỉ thực hiện phân bổ nhỏ mới cho mỗi nút.

Tuy nhiên, nhân đôi mảng sao lưu được O(1)khấu hao, do đó, nó được xem xét đến độ trễ tối đa. Đề cập ở đây .

Triết học

  • Các BST duy trì một tài sản toàn cầu giữa cha mẹ và tất cả con cháu (trái nhỏ hơn, phải lớn hơn).

    Nút trên cùng của BST là phần tử ở giữa, đòi hỏi kiến ​​thức toàn cầu để duy trì (biết có bao nhiêu phần tử nhỏ hơn và lớn hơn).

    Tài sản toàn cầu này đắt hơn để duy trì (log n insert), nhưng cung cấp các tìm kiếm mạnh mẽ hơn (tìm kiếm log n).

  • Heaps duy trì một tài sản địa phương giữa cha mẹ và con cái trực tiếp (cha mẹ> con cái).

    Nút trên cùng của một đống là phần tử lớn, chỉ yêu cầu kiến ​​thức địa phương để duy trì (biết cha mẹ của bạn).

So sánh BST vs Heap vs Hashmap:

  • BST: có thể là hợp lý:

    • bộ không có thứ tự (một cấu trúc xác định xem một phần tử đã được chèn trước đó hay chưa). Nhưng hashmap có xu hướng tốt hơn do chèn vào khấu hao O (1).
    • máy phân loại. Nhưng heap thường tốt hơn ở đó, đó là lý do tại sao heapsort được biết đến rộng rãi hơn nhiều so với phân loại cây
  • heap: chỉ là một máy phân loại. Không thể là một tập hợp không có thứ tự hiệu quả, bởi vì bạn chỉ có thể kiểm tra nhanh phần tử nhỏ nhất / lớn nhất.

  • bản đồ băm: chỉ có thể là một tập hợp không có thứ tự, không phải là một máy sắp xếp hiệu quả, bởi vì băm trộn lẫn bất kỳ thứ tự nào.

Danh sách liên kết đôi

Một danh sách liên kết đôi có thể được xem là tập hợp con của heap trong đó mục đầu tiên có mức độ ưu tiên cao nhất, vì vậy hãy so sánh chúng ở đây:

  • chèn:
    • Chức vụ:
      • danh sách liên kết đôi: mục được chèn phải là đầu tiên hoặc cuối cùng, vì chúng ta chỉ có các con trỏ tới các phần tử đó.
      • heap binary: mục được chèn có thể kết thúc ở bất kỳ vị trí nào. Ít hạn chế hơn danh sách liên kết.
    • thời gian:
      • danh sách liên kết đôi: O(1)trường hợp xấu nhất vì chúng tôi có con trỏ tới các mục và việc cập nhật thực sự đơn giản
      • heap binary: O(1)trung bình, do đó tồi tệ hơn danh sách liên kết. Đánh đổi để có vị trí chèn chung hơn.
  • tìm kiếm: O(n)cho cả hai

Một trường hợp sử dụng cho điều này là khi khóa của heap là dấu thời gian hiện tại: trong trường hợp đó, các mục mới sẽ luôn đi đến đầu danh sách. Vì vậy, chúng ta thậm chí có thể quên hoàn toàn dấu thời gian chính xác và chỉ giữ vị trí trong danh sách là ưu tiên.

Điều này có thể được sử dụng để thực hiện bộ đệm LRU . Giống như đối với các ứng dụng heap như Dijkstra , bạn sẽ muốn giữ một hashmap bổ sung từ khóa đến nút tương ứng của danh sách, để tìm nút nào cần cập nhật nhanh chóng.

So sánh các BST cân bằng khác nhau

Mặc dù thời gian chèn và tìm tiệm cận cho tất cả các cấu trúc dữ liệu thường được phân loại là "BST cân bằng" mà tôi đã thấy cho đến nay là như nhau, các BBST khác nhau có sự đánh đổi khác nhau. Tôi chưa nghiên cứu đầy đủ về vấn đề này, nhưng sẽ rất tốt nếu tóm tắt những sự đánh đổi này ở đây:

  • Cây đỏ đen . Xuất hiện là BBST được sử dụng phổ biến nhất kể từ năm 2019, ví dụ: đây là BBST được sử dụng bởi triển khai GCC 8.3.0 C ++
  • Cây AVL . Có vẻ cân bằng hơn một chút so với BST, vì vậy có thể tốt hơn cho việc tìm độ trễ, với chi phí tìm thấy đắt hơn một chút. Wiki tóm tắt: "Cây AVL thường được so sánh với cây đen Red do cả hai đều hỗ trợ cùng một tập hợp hoạt động và mất [cùng] thời gian cho các hoạt động cơ bản. Đối với các ứng dụng chuyên sâu tra cứu, cây AVL nhanh hơn cây đen đỏ vì Chúng cân bằng chặt chẽ hơn. Tương tự như cây đen đỏ, cây AVL cân bằng chiều cao. Nhìn chung, cả hai đều không cân bằng trọng lượng hoặc không cân bằng cho bất kỳ mu <1/2; nghĩa là các nút anh chị em có thể có rất nhiều số lượng con cháu khác nhau. "
  • WAVL . Bài viết gốc đề cập đến những lợi thế của phiên bản đó về các giới hạn trong hoạt động tái cân bằng và xoay vòng.

Xem thêm

Câu hỏi tương tự trên CS: /cs/27860/whats-the-difference-b between-a-binary-search-tree-and-a- binary-heap


4
I + 1ed, nhưng phần chèn heap nhị phân O (1) trung bình chỉ là một liên kết chết và "slide" chỉ nêu yêu cầu mà không cần chứng minh. Ngoài ra tôi nghĩ nó sẽ giúp làm rõ rằng "trường hợp trung bình" ở đây có nghĩa là trung bình giả định rằng các giá trị được chèn đến từ một số phân phối cụ thể , vì vậy tôi không chắc chắn "kẻ giết người" tính năng này thực sự như thế nào.
j_random_hacker

3
BST và BST cân bằng dường như được sử dụng thay thế cho nhau. Cần làm rõ rằng câu trả lời đề cập đến BST cân bằng để tránh nhầm lẫn.
gkalpak

2
@Bulat Tôi cảm thấy chúng tôi lạc đề một chút, nhưng nếu chúng tôi muốn cả max và min cùng một lúc, chúng tôi có thể gặp vấn đề với việc duy trì hai đống nếu chúng tôi không cẩn thận - stackoverflow.com/a/1098454/7154924 . Có lẽ tốt hơn để sử dụng một đống tối đa (do Atkinson và cộng sự), được thiết kế đặc biệt cho mục đích này.
Flow2k

1
@CiroSantilli 心 心: Tôi không hiểu tại sao thao tác xóa của một đống nhị phân là O (log n). Điều này chỉ hoạt động nếu bạn có một con trỏ tới phần tử trong heap, nhưng trong hầu hết các trường hợp sử dụng, bạn có khóa và bạn cần tìm phần tử trước tiên lấy O (n).
Ricola

5
chèn heap là log (n) không o (1)
Bobo

78

Heap chỉ đảm bảo rằng các phần tử ở mức cao hơn lớn hơn (đối với heap tối đa) hoặc nhỏ hơn (đối với heap tối thiểu) so với các phần tử ở mức thấp hơn, trong khi BST đảm bảo thứ tự (từ "trái" sang "phải"). Nếu bạn muốn các yếu tố được sắp xếp, đi với BST.


8
"Heap chỉ đảm bảo rằng các phần tử ở cấp độ cao hơn lớn hơn (đối với heap tối đa) hoặc nhỏ hơn (đối với heap tối thiểu) so với các phần tử ở cấp độ thấp hơn," - heap không thực thi điều này trên mỗi cấp độ , mà chỉ trong cha mẹ chuỗi. [1, 5, 9, 7, 15, 10, 11]đại diện cho một heap min hợp lệ, nhưng 7ở mức 3 nhỏ hơn 9ở cấp 2. Để trực quan hóa, hãy xem ví dụ 2519các phần tử trong hình ảnh Wikipedia mẫu cho heap . (Cũng lưu ý rằng mối quan hệ bất bình đẳng giữa các yếu tố không nghiêm ngặt, vì các yếu tố không nhất thiết phải là duy nhất.)
Daniel Andersson

Xin lỗi vì nhập cảnh muộn nhưng tôi chỉ muốn có được sự rõ ràng. Nếu Heap nhị phân được sắp xếp, trường hợp xấu nhất cho tìm kiếm sẽ là log n ngay. Vì vậy, trong trường hợp đó, các Heaps nhị phân được sắp xếp tốt hơn so với Cây tìm kiếm nhị phân (BST đỏ-đen). Cảm ơn bạn
Krishna

50

Khi nào nên sử dụng một đống và khi nào sử dụng BST

Heap tốt hơn ở findMin / findMax ( O(1)), trong khi BST tốt ở tất cả find ( O(logN)). Chèn là O(logN)cho cả hai cấu trúc. Nếu bạn chỉ quan tâm đến findMin / findMax (ví dụ: liên quan đến ưu tiên), hãy đi với heap. Nếu bạn muốn mọi thứ được sắp xếp, hãy đi với BST.

Một vài slide đầu tiên từ đây giải thích mọi thứ rất rõ ràng.


3
Trong khi insert là logarit cho cả hai trong trường hợp xấu nhất, thì heap insert trung bình mất thời gian không đổi. (Vì hầu hết các yếu tố hiện có đều ở dưới cùng, nên trong hầu hết các trường hợp, một yếu tố mới sẽ chỉ phải tăng một hoặc hai cấp độ, nếu có.)
johncip

1
@xysun Tôi nghĩ BST tốt hơn trong findMin & findMax stackoverflow.com/a/27074221/764592
Yeo

2
@Yeo: Heap tốt hơn cho findMin xor findMax. Nếu bạn cần cả hai , thì BST là tốt hơn.
Vịt Mooing

1
Tôi nghĩ rằng đây chỉ là một quan niệm sai lầm phổ biến. Một cây nhị phân có thể dễ dàng sửa đổi để tìm min và max như được chỉ bởi Yeo. Đây thực sự là một hạn chế của heap: tìm thấy hiệu quả duy nhất là tối thiểu hoặc tối đa. Lợi thế thực sự của heap là chèn trung bình O (1) như tôi giải thích: stackoverflow.com/a/29548834/895245
Ciro Santilli 冠状 六四 事件 法轮功

1
Câu trả lời của Ciro Santilli tốt hơn nhiều: stackoverflow.com/a/29548834/2873507
Vic Seedoubleyew

9

Như đã đề cập bởi những người khác, Heap có thể làm findMin hoặc findMax trong O (1) nhưng không phải cả hai trong cùng một cấu trúc dữ liệu. Tuy nhiên tôi không đồng ý rằng Heap tốt hơn trong findMin / findMax. Trong thực tế, với một sửa đổi nhỏ, BST có thể thực hiện cả hai findMin findMax trong O (1).

Trong BST được sửa đổi này, bạn theo dõi nút tối thiểu và nút tối đa mỗi khi bạn thực hiện một thao tác có khả năng sửa đổi cấu trúc dữ liệu. Ví dụ: trong thao tác chèn, bạn có thể kiểm tra xem giá trị min có lớn hơn giá trị mới chèn không, sau đó gán giá trị min cho nút mới được thêm vào. Kỹ thuật tương tự có thể được áp dụng trên giá trị tối đa. Do đó, BST này chứa những thông tin mà bạn có thể truy xuất chúng trong O (1). (giống như đống nhị phân)

Trong BST này (BST cân bằng), khi bạn pop minhoặc pop max, giá trị min tiếp theo được gán là sự kế thừa của nút min, trong khi giá trị tối đa tiếp theo được gán là tiền thân của nút max. Do đó, nó thực hiện trong O (1). Tuy nhiên, chúng ta cần phải cân bằng lại cây, do đó nó sẽ vẫn chạy O (log n). (giống như đống nhị phân)

Tôi sẽ được quan tâm để nghe suy nghĩ của bạn trong bình luận dưới đây. Cảm ơn :)

Cập nhật

Tham chiếu chéo cho câu hỏi tương tự Chúng ta có thể sử dụng cây tìm kiếm nhị phân để mô phỏng hoạt động heap không? để thảo luận thêm về mô phỏng Heap bằng BST.


Tại sao bạn không đồng ý? bạn có muốn chia sẻ với suy nghĩ của bạn dưới đây?
Yeo

Bạn chắc chắn có thể lưu trữ giá trị tối đa và / hoặc tối thiểu của một BST, nhưng sau đó điều gì xảy ra nếu bạn muốn bật nó? Bạn phải tìm kiếm cây để loại bỏ nó, sau đó tìm kiếm lại max / min mới, cả hai đều là hoạt động O (log n). Đó là thứ tự tương tự như chèn và xóa trong một đống ưu tiên, với hằng số tồi tệ hơn.
Justin

@JustinLardinois Xin lỗi, tôi quên làm nổi bật điều này trong câu trả lời của tôi. Trong BST, khi bạn thực hiện pop min, giá trị min tiếp theo được gán là sự kế thừa của nút min. và nếu bạn bật max, giá trị tối đa tiếp theo sẽ được chỉ định là tiền thân của nút max. Do đó, nó vẫn thực hiện trong O (1).
Yeo

Sửa lỗi: cho popMinhoặc popMaxnó không phải là O (1), mà là O (log n) vì nó phải là BST cân bằng cần phải cân bằng lại mỗi thao tác xóa. Do đó, nó giống như heap nhị phân popMinhoặc popMaxchạy O (log n)
Yeo

2
Bạn có thể nhận được min / max đầu tiên, nhưng nhận được min / max thứ k sẽ trở lại độ phức tạp BST bình thường.
Hỗn loạn

3

Cây tìm kiếm nhị phân sử dụng định nghĩa: với mỗi nút, nút bên trái của nó có giá trị (khóa) ít hơn và nút ở bên phải của nó có giá trị (khóa) lớn hơn.

Trong trường hợp heap, việc triển khai cây nhị phân sử dụng định nghĩa sau:

Nếu A và B là các nút, trong đó B là nút con của A, thì giá trị (khóa) của A phải lớn hơn hoặc bằng giá trị (khóa) của B.That là, khóa (A) (B) ).

http://wiki.answers.com/Q/Difference_b between_binary_search_tree_and_heap_tree

Tôi đã chạy trong cùng một câu hỏi ngày hôm nay cho kỳ thi của tôi và tôi đã làm đúng. nụ cười ... :)


"Heap, là một triển khai của cây nhị phân" - chỉ ra rằng một đống là một loại cây nhị phân, không phải là một loại BST
Saad

3

Một cách sử dụng BST khác trên Heap; bởi vì một sự khác biệt quan trọng:

  • việc tìm kiếm người kế nhiệm và người tiền nhiệm trong BST sẽ mất thời gian O (h). (O (logn) trong BST cân bằng)
  • trong khi ở Heap, sẽ mất O (n) thời gian để tìm người kế vị hoặc tiền thân của một số yếu tố.

Sử dụng BST trên một đống : Bây giờ, hãy nói rằng chúng tôi sử dụng cấu trúc dữ liệu để lưu trữ thời gian hạ cánh của các chuyến bay. Chúng tôi không thể sắp xếp chuyến bay hạ cánh nếu chênh lệch thời gian hạ cánh nhỏ hơn 'd'. Và giả sử nhiều chuyến bay đã được lên kế hoạch hạ cánh trong cấu trúc dữ liệu (BST hoặc Heap).

Bây giờ, chúng tôi muốn sắp xếp một chuyến bay khác sẽ hạ cánh tại t . Do đó, chúng ta cần tính toán sự khác biệt của t với người kế nhiệm và người tiền nhiệm của nó (nên> d). Vì vậy, chúng ta sẽ cần một BST cho việc này, nó sẽ nhanh, tức là trong O (logn) nếu được cân bằng.

CHỈNH SỬA:

Sắp xếp BST mất thời gian O (n) để in các phần tử theo thứ tự được sắp xếp (Inorder traversal), trong khi Heap có thể làm điều đó trong thời gian O (n logn). Heap trích xuất phần tử min và sắp xếp lại mảng, điều này làm cho nó thực hiện sắp xếp theo thời gian O (n logn).


1
Đúng. Đó là từ chưa sắp xếp để sắp xếp thứ tự. O (n) thời gian để sắp xếp theo thứ tự của BST, cung cấp trình tự được sắp xếp. Trong khi ở Heaps, bạn trích xuất phần tử min và sau đó heapify trong thời gian O (log n). Vì vậy, sẽ mất O (n logn) để trích xuất n phần tử. Và nó sẽ để lại cho bạn một chuỗi sắp xếp.
CODError

from unsorted to sorted sequence. O(n) time for inorder traversal of a BST, which gives sorted sequence.Chà, từ trình tự chưa được sắp xếp đến BST Tôi không biết một phương pháp dựa trên so sánh khóa với thời gian ít hơn O (n logn), chi phối BST thành phần trình tự. (Trong khi đó có O (n) heap xây dựng.). Tôi coi điều đó là công bằng (nếu vô nghĩa) khi các đống trạng thái gần với sự không sắp xếp và các BST được sắp xếp.
greybeard

Điều tôi đang cố gắng giải thích ở đây là nếu bạn có BST và Heap gồm n phần tử => thì tất cả các phần tử có thể được in theo thứ tự được sắp xếp từ cả hai cấu trúc dữ liệu và BST có thể thực hiện trong thời gian O (n) ), trong khi Heap sẽ mất thời gian O (n logn). Tôi không hiểu những gì bạn đang cố gắng nói ở đây. Làm thế nào để bạn nói BST sẽ cung cấp cho bạn thứ tự sắp xếp trong O (n logn).
CODError

Tôi nghĩ bạn cũng đang cân nhắc thời gian để xây dựng BST và Heap. Nhưng tôi giả sử bạn đã có nó, rằng bạn đã xây dựng nó theo thời gian và bây giờ bạn muốn có được kết quả được sắp xếp. Tôi không nhận được quan điểm của bạn?
CODError

1
Đã chỉnh sửa ... Tôi hy vọng bạn hài lòng ngay bây giờ; p và cho +1 nếu đúng.
CODError

1

Chèn tất cả n phần tử từ một mảng vào BST sẽ lấy O (n logn). n elemnts trong một mảng có thể được chèn vào một đống trong thời gian O (n). Điều này mang lại cho heap một lợi thế nhất định


0

Heap chỉ đảm bảo rằng các phần tử ở cấp cao hơn lớn hơn (đối với heap tối đa) hoặc nhỏ hơn (đối với heap tối thiểu) so với các phần tử ở cấp thấp hơn

Tôi thích câu trả lời trên và đưa nhận xét của tôi chỉ cụ thể hơn cho nhu cầu và cách sử dụng của tôi. Tôi phải lấy danh sách n vị trí tìm khoảng cách từ mỗi vị trí đến điểm cụ thể nói (0,0) và sau đó trả về các vị trí am có khoảng cách nhỏ hơn. Tôi đã sử dụng Hàng đợi ưu tiên là Heap. Để tìm khoảng cách và đưa vào heap, tôi phải mất n (log (n)) n-vị trí log (n) mỗi lần chèn. Sau đó, để có được m với khoảng cách ngắn nhất, phải mất m (log (n)) m-location log (n) xóa đi sự nóng lên.

Nếu tôi phải làm điều này với BST, nó sẽ khiến tôi phải chèn trường hợp xấu nhất. (Giả sử giá trị đầu tiên rất nhỏ và tất cả các giá trị khác kéo dài hơn và dài hơn và cây kéo dài sang phải con hoặc trái trong trường hợp nhỏ hơn và nhỏ hơn. Min sẽ mất thời gian O (1) nhưng một lần nữa tôi phải cân bằng. Vì vậy, từ tình huống của tôi và tất cả các câu trả lời trên tôi nhận được là khi bạn chỉ sau khi các giá trị ở mức tối thiểu hoặc tối đa cho đống.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.