Khi nào tôi muốn sử dụng một đống?


92

Ngoài câu trả lời rõ ràng về Hàng đợi ưu tiên, khi nào thì một đống sẽ hữu ích trong cuộc phiêu lưu lập trình của tôi?


8
Có rất nhiều câu trả lời hay ở đây, vì vậy tôi sẽ giải thích bằng "khi một đống không đủ lớn."
Don Werve

Câu trả lời:


121

Sử dụng nó bất cứ khi nào bạn cần truy cập nhanh vào mục lớn nhất (hoặc nhỏ nhất), vì mục đó sẽ luôn là phần tử đầu tiên trong mảng hoặc ở gốc của cây.

Tuy nhiên, phần còn lại của mảng được giữ một phần không được sắp xếp. Do đó, chỉ có thể truy cập tức thời vào mục lớn nhất (nhỏ nhất). Việc chèn nhanh chóng, vì vậy đó là một cách tốt để xử lý các sự kiện hoặc dữ liệu sắp đến và luôn có quyền truy cập vào thông tin sớm nhất / lớn nhất.

Hữu ích cho hàng đợi ưu tiên, bộ lập lịch (nơi mong muốn có mục sớm nhất), v.v.

Một heap là một cây mà giá trị của nút cha lớn hơn giá trị của bất kỳ nút con nào của nó.

Nếu bạn nghĩ về một đống như một cây nhị phân được lưu trữ theo thứ tự tuyến tính theo độ sâu, với nút gốc đầu tiên (sau đó là nút con của nút đó tiếp theo, sau đó là nút con tiếp theo); thì nút con của nút ở chỉ số N là 2N + 1 và 2N + 2. Thuộc tính này cho phép truy cập nhanh theo chỉ mục. Và vì đống được thao tác bằng cách hoán đổi các nút, điều này cho phép phân loại tại chỗ.


3
Cũng lưu ý rằng nó có thể là một loại NlogN được đảm bảo thuận tiện mà không yêu cầu phân bổ mảng bổ sung
Overflown

38
Thật

21
@ vivekian2 Lý do duy nhất tôi ở đây là vì tôi sắp có một cuộc phỏng vấn.
byxor

tại sao không sử dụng một lớp ngăn xếp với một ngăn xếp phụ trợ để theo dõi mục lớn nhất (hoặc nhỏ nhất). truy xuất là O (1)
Ridhwaan Shakeel

@RidhwaanShakeel Nếu bạn sử dụng ngăn xếp, vật phẩm của bạn sẽ luôn được đặt trên đầu, điều gì sẽ xảy ra nếu vị trí của vật phẩm cần được xác định dựa trên một số thuộc tính của vật phẩm như sự kiện lớn nhất (dựa trên số người tham gia sự kiện).
SandeepGodara

49

Heap là cấu trúc cho phép truy cập nhanh đến giá trị tối thiểu hoặc giá trị tối đa .

Nhưng tại sao bạn muốn điều đó? Bạn chỉ có thể kiểm tra mọi mục nhập trên add để xem nó là nhỏ nhất hay lớn nhất. Bằng cách này, bạn luôn có giá trị nhỏ nhất hoặc lớn nhất trong thời gian không đổi O(1).

Câu trả lời là bởi vì đống cho phép bạn kéo nhỏ nhất hoặc lớn nhất và nhanh chóng biết TIẾP THEO nhỏ nhất hoặc lớn nhất . Đó là lý do tại sao nó được gọi là Hàng đợi ưu tiên.

Ví dụ về thế giới thực (mặc dù thế giới không công bằng lắm):

Giả sử bạn có một bệnh viện trong đó bệnh nhân được theo dõi dựa trên độ tuổi của họ. Những người lớn tuổi nhất luôn được tham dự đầu tiên, bất kể khi nào anh ta / cô ta xếp hàng.

Bạn không thể chỉ theo dõi người cũ nhất bởi vì nếu bạn kéo họ ra ngoài, bạn sẽ không biết người cũ tiếp theo. Để giải quyết vấn đề bệnh viện này, bạn triển khai một đống tối đa . Theo định nghĩa, đống này được sắp xếp một phần. Điều này có nghĩa là bạn không thể sắp xếp bệnh nhân theo độ tuổi của họ, nhưng bạn biết rằng những người già nhất luôn nằm trong top đầu, vì vậy bạn có thể kéo một bệnh nhân ra trong thời gian liên tục O(1)và cân bằng lại đống thời gian trong nhật ký O(log N).

Ví dụ phức tạp hơn:

Giả sử bạn có một chuỗi các số nguyên và bạn muốn theo dõi median. Trung vị là số ở giữa một mảng có thứ tự.

Thí dụ:

[1, 2, 5, 7, 23, 27, 31]

Trong trường hợp trên, 7là trung vị vì mảng chứa các số nhỏ hơn [1, 2, 5]có cùng kích thước với mảng chứa các số lớn hơn [23, 27, 31]. Thông thường, nếu mảng có một số phần tử lẻ, thì trung vị là trung bình cộng của 2 phần tử ở giữa, ví dụ (5 + 7)/2.

Bây giờ, làm cách nào để bạn theo dõi dải phân cách? Bằng cách có 2 đống , một đống nhỏ nhất chứa các số nhỏ hơn trung vị hiện tại và một đống tối đa chứa các số lớn hơn trung vị hiện tại. Bây giờ, nếu những đống này luôn cân bằng, thì 2 đống sẽ chứa cùng một số phần tử hoặc một cái sẽ có nhiều hơn 1 phần tử, nhiều nhất.

Khi bạn thêm một phần tử mới vào chuỗi, nếu số nhỏ hơn số trung vị hiện tại, bạn thêm phần tử đó vào đống nhỏ nhất, nếu không, bạn thêm phần tử đó vào đống tối đa. Bây giờ, nếu các đống không cân bằng (một đống có nhiều hơn 1 phần tử hơn cái còn lại), bạn kéo một phần tử từ đống lớn nhất và thêm vào phần nhỏ nhất. Bây giờ chúng đã cân bằng.


6
Ví dụ phức tạp hơn là tuyệt vời! Tôi chắc chắn sẽ thử điều này vào một lúc nào đó. Tuy nhiên, tôi nghĩ rằng có một sai lầm nhỏ trong ví dụ của bạn. Vì chúng ta cần lấy giá trị trung bình bằng cách lấy trung bình hai phần tử ở giữa. Tôi giả sử rằng chúng ta cần sử dụng một heap tối thiểu để lưu trữ các số lớn hơn trung vị hiện tại và một heap tối đa để lưu trữ các số nhỏ hơn trung vị hiện tại. Bằng cách này, chúng ta có thể trích xuất hai phần tử ở giữa trong thời gian không đổi và tính giá trị trung bình? Tôi có đúng không?
Calvin Ku

12

Đặc điểm của heap là nó là cấu trúc duy trì dữ liệu được sắp xếp theo thứ tự; do đó, nó là một sự cân bằng tốt giữa chi phí duy trì một đơn đặt hàng hoàn chỉnh và chi phí tìm kiếm thông qua sự hỗn loạn ngẫu nhiên. Đặc tính đó được sử dụng trên nhiều thuật toán, chẳng hạn như lựa chọn, sắp xếp hoặc phân loại.

Một đặc điểm hữu ích khác của heap là nó có thể được tạo tại chỗ từ một mảng!


3

Cũng tốt cho các thuật toán lựa chọn (tìm giá trị tối thiểu hoặc tối đa)


3

bất cứ lúc nào khi bạn sắp xếp một danh sách tạm thời, bạn nên xem xét đống.


0

Bạn có thể sử dụng minHeap hoặc maxHeap khi bạn muốn truy cập các phần tử nhỏ nhất và lớn nhất tương ứ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.