Thuật toán bồi dưỡng. Tại sao heapsort là một thuật toán insort?


15

Tôi không thể hiểu tại sao heapsort được coi là một thuật toán sắp xếp tại chỗ .

Ý tôi là một cấu trúc dữ liệu bổ sung được điền với các phần tử của mảng được sắp xếp tức là một đống, được sử dụng để hỗ trợ trích xuất giá trị min và quá trình sắp xếp.

Vì vậy, có thể tôi đang hiểu sai định nghĩa của inplace ở đây?

Nhưng sắp xếp chèn chẳng hạn, rõ ràng đó là thuật toán tại chỗ, tức là không cần thêm bộ nhớ cho các phần tử.

Vậy tại sao nó được coi là tại chỗ?

Câu trả lời:


12

Ý tôi là một cấu trúc dữ liệu bổ sung được điền với các phần tử của mảng được sắp xếp, nghĩa là một đống, được sử dụng để hỗ trợ trích xuất giá trị tối thiểu và quá trình sắp xếp.

Không. Mảng được biến đổi để phù hợp với ràng buộc heap mà không sử dụng nhiều hơn O (1) bộ nhớ phụ. (Trong thực tế tất cả những gì bạn cần là bộ nhớ bổ sung đủ để chứa một phần tử của mảng, cho mục đích trao đổi, cộng với một boolean hoặc hai và một biến vòng lặp hoặc hai).

Ok, về mặt kỹ thuật, có thể là heapsort thường được giải thích là sử dụng một đống riêng biệt, nhưng hoàn toàn có thể thực hiện tại chỗ.


3
Nơi duy nhất tôi mong đợi để xem "heapsort" với một heap riêng (bằng mã) là trong một ngôn ngữ chức năng như Haskell, vì lý do tương tự rằng "Quicksort" chức năng thông thường không đúng chỗ - các lập trình viên chức năng thích danh sách của họ rất nhiều và sắp xếp tại chỗ là trạng thái - nó thay đổi trạng thái của mảng / bất cứ thứ gì có chứa dữ liệu. Những câu trích dẫn đáng sợ bởi vì tôi thực sự không chấp nhận rằng quicksort ngoài địa điểm hoàn toàn là một quicksort, hoặc một heapsort ngoài địa điểm là một heapsort - ít nhất là không nói rõ rằng nó không ở trong địa điểm.
Steve314

1
@ Steve314, tôi nghĩ rằng tôi đã thấy một số tài liệu giảng dạy nói lên điều gì đó về tác dụng của việc "đặt nó thành một đống và sau đó kéo các phần tử ra từng cái một và đặt chúng vào một mảng". Nhưng khi vừa kiểm tra CLR tôi có thể báo cáo rằng họ có hiển thị phiên bản tại chỗ.
Peter Taylor

2
@PeterTaylor: Vâng, cuốn sách tôi đang xem xét (Skiena) đã trình bày heapsort bằng cách xây dựng một đống thêm.
dùng10326

4

Bạn có thể thiếu hiểu biết cơ bản rằng một mảng có thể được sử dụng để chỉ định bố cục của cây.

Giả sử bạn có một cây nhị phân và một nút bên trong nằm ở chỉ số i của mảng. Sau đó, chỉ số mảng của cha mẹ và con của nút đó có thể được tìm thấy bởi:

Parent(i) = floor(i/2)
Left child(i) = 2i
Right child(i) = 2i + 1

Xem:

http://www.personal.kent.edu/~rmuhamma/Alacticms/MyAlacticms/Sorting/heapSort.htmlm

Vì heap có thể được giữ và tổ chức hoàn toàn trong một mảng, nên heapsort có thể chạy tại chỗ bằng cách di chuyển các phần tử xung quanh bên trong mảng đầu vào. Thật vậy, heap được xây dựng và thao tác bằng cách sử dụng mảng đầu vào ban đầu.


: Tôi biết về điều này. Các vấn đề dường như là cuốn sách tôi đang đọc được trình bày heapsort bằng cách sử dụng một đống riêng biệt. Tôi không hiểu hoặc nghĩ rằng bản trình bày này là để dễ hiểu thuật toán hơn (có lẽ? Không chắc tại sao nó lại là trình bày như vậy)
user10326

Tôi đặc biệt khuyên bạn nên mua cuốn sách "Giới thiệu về thuật toán" của Cormen, et al. Nó trả lời rõ ràng tất cả các câu hỏi liên quan đến thuật toán. Nếu bạn nghiêm túc về nghề nghiệp là một nhà khoa học máy tính hoặc kỹ sư phần mềm, thì bạn cần phải có cuốn sách này.
stackoverflowuser2010

1

Nếu, như bạn nói, người ta thực sự cần một cấu trúc bổ sung để xây dựng heap thì heapsort thực sự sẽ KHÔNG phải là một thuật toán sắp xếp tại chỗ.

Tuy nhiên, đây không phải là trường hợp. Bạn có thể xây dựng heap trên cùng một mảng mà bạn muốn sắp xếp và sau đó bạn áp dụng thuật toán heapsort, để nó sắp xếp đúng chỗ.


Về cơ bản, có một thuật toán "heapify" được sử dụng để sắp xếp lại dữ liệu trong một mảng để nó tuân thủ các quy tắc của một đống trong thời gian IIRC O (n). Xem mã giả trên các lập trình viên.stackexchange.com/questions/116904/ . Sau đó, vấn đề chủ yếu là thực hiện trích xuất gốc heap lặp đi lặp lại và theo dõi xem bao nhiêu mảng vẫn là "heap" và kết quả cuối cùng được sắp xếp là bao nhiêu.
Steve314

0

Trong khoa học máy tính, thuật toán tại chỗ (hoặc bằng tiếng Latin in situ) là thuật toán biến đổi đầu vào bằng cách sử dụng cấu trúc dữ liệu với một lượng không gian lưu trữ bổ sung nhỏ, không đổi. Đầu vào thường được ghi đè bởi đầu ra khi thuật toán thực thi. Một thuật toán không tại chỗ đôi khi được gọi là không đúng chỗ hoặc không đúng chỗ.

Wikipedia - Thuật toán tại chỗ


Vậy tại sao sáp nhập được coi là một thuật toán không tại chỗ sau đó?
dùng10326

3
Đây không phải là một câu trả lời hữu ích. Nó không có gì để làm với heapsort và không trả lời câu hỏi.
stackoverflowuser2010

Tất nhiên nó có một cái gì đó để làm với heapsort. Heapsort là một thuật toán sắp xếp tại chỗ, cần phải rõ ràng từ định nghĩa. Trong thực tế, nó đã được liên kết từ trang heapsort.
Rein Henrichs

0

Nó được xem xét tại chỗ vì các yêu cầu về không gian của nó là không đáng kể (không đổi hoặc không có gì cả nếu bạn đang sử dụng các thao tác bitwise để trao đổi các mục). MergeSort, chẳng hạn, không đúng chỗ vì bộ đầu vào không được sửa đổi trong mỗi lần lặp của ví dụ tìm kiếm.

Cách tốt nhất để minh họa sự khác biệt giữa thuật toán tại chỗ và thuật toán ngoài vị trí có lẽ là xem xét mã đảo ngược chuỗi C / C ++ sau đây thực hiện (từ K & R):

void reverse(char s[])
{
      int c, i, j;

      for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
         c = s[i];
         s[i] = s[j];
         s[j] = c;
      }
}

Ví dụ, nếu bạn đọc chuỗi đầu vào từ cuối và đặt các ký tự vào bộ đệm khác, thì đó sẽ là thuật toán đảo ngược chuỗi không đúng chỗ.


1
Mergesort được damned gây phiền nhiễu - nó dễ dàng để sai thuyết phục bản thân rằng bạn có một chiến lược tại chỗ. Thông thường, nó chỉ hoạt động cho các mảng nhỏ. Tuy nhiên, tôi nghĩ rằng tôi đã tải xuống một bài báo khi một người nào đó thực hiện một biến thể tại chỗ của thuật toán sắp xếp hợp nhất. Tôi sẽ xem nếu tôi có thể tìm lại nó.
Steve314
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.