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?
Câu trả lời:
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ỗ.
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.
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)
.
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, 7
là 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.
Đặ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!