5.2 Mergesort — một O(n log n) phân loại thuật toán
Mergesort là một straightfo
rward áp dụng các nguyên tắc phân chia và chinh phục. Các
phân loại thứ tự được chia thành hai phần của về bằng kích thước. Các bộ phận là sortedrecursively và các bộ phận được sắp xếp được sáp nhập vào một chuỗi duy nhất được sắp xếp. Cách tiếp cận là efficient bởi vì việc sáp nhập hai chuỗi được sắp xếp một và b là khá đơn giản.
Các yếu tố nhỏ nhất trên toàn cầu là một trong hai các yếu tố chính của một hoặc các yếu tố chính của
b. Vì vậy, chúng tôi di chuyển các yếu tố nhỏ hơn để đầu ra, nhiều yếu tố nhỏ thứ hai
104
5 phân loại và lựa chọn
chức năng mergeSort (e1,..., en): trình tự nguyên tố
nếu n = 1 sau đó trở lại e1
khác trở lại kết hợp (mergeSort (e1,..., n e/2), mergeSort (e
n/2 1,..., en))
việc sáp nhập hai chuỗi đại diện như các danh sách
kết hợp chức năng (a, b: trình tự nguyên tố): trình tự nguyên tố
c: =
loop
bất biến a, b, và c đều được sắp xếp và ∀e ∈ c, e ∈ b u: e ≤ e
nếu a.isEmptythen c.concat(b); trở về c
nếu b.isEmptythen c.concat(a); trở về c
nếu a.first ≤ b.first sau đó c.moveToBack (a.first)
elsec.moveToBack (b.first)
Fig. 5.2. Mergesort
tách
tách
tách
merge
Merge
merge
2718281
271
2
8281
một
1, 2, 7
2, 7
2, 7
7
7
b
1, 2, 8, 8
1, 2, 8, 8
2, 8, 8
2, 8, 8
8, 8
8, 8
hoạt động
di chuyển một
1move b
1, 1move một
1, 1, 2move b
1, 1, 2, 2move một
1, 1, 2, 2, 7move một
1, 1, 22, 7, 8, 8 concat b
c
71 82 81
7 18 2 8 1
17 28 18
127
1288
1222788
hình 5.3. Thực hiện của mergeSort (2, 7, 1, 8, 2, 8, 1). Minh hoạ phần trái đệ quy trong
mergeSort và phần bên phải minh họa kết hợp trong các cuộc gọi ngoài cùng.
sử dụng cùng một phương pháp tiếp cận và lặp cho đến khi tất cả các yếu tố đã được chuyển sang đầu ra.
con số 5,2 cho mã giả và con số 5.3 minh hoạ một thực thi mẫu. Chúng tôi có
xây dựng thói quen merging cho chuỗi đại diện như các danh sách tuyến tính như giới thiệu
trong phần 3.1. Lưu ý rằng không có phân bổ và deallocation của danh mục là cần thiết. Mỗi
lặp đi lặp lại của vòng bên trong của hợp nhất thực hiện một phần tử so sánh và di chuyển
một yếu tố để đầu ra. Lặp đi lặp lại mỗi mất thời gian liên tục. Do đó hợp nhất chạy trong
thời gian tuyến tính.
định lý 14. Kết hợp chức năng áp dụng cho các chuỗi của tổng chiều dài n thực hiện trong time
O(n) và thực hiện tại hầu hết n − 1 phần tử so sánh.
Trong thời gian chạy của mergesort chúng ta có được.
định lý 15. Mergesort chạy trong thời gian O (n log n) và thực hiện không có đăng nhập nhiều hơn n n
nguyên tố so sánh.
bằng chứng. Hãy để C(n) biểu thị số trường hợp tồi tệ nhất của nguyên tố so sánh thực hiện.
chúng tôi có C(1) = 0 và C(n) ≤ C (n/2) C (n/2) n − 1 bằng cách sử dụng định lý 14.
5.2 Mergesort — một thuật toán phân loại O(n log n)
105
Định lý tổng thể cho tái phát quan hệ (6) cho thấy rằng C(n) = O(n log n).
chúng tôi đưa ra hai chứng minh. Vòng bằng chứng cho thấy C(n) ≤ 2n log n và chứng minh thứ hai
cho thấy C(n) ≤ n log n.
n một sức mạnh của hai, define D(1) = 0 và D(n) = 2D(n/2) n. Sau đó D(n) =
n log n n một sức mạnh của hai theo định lý tổng thể quan hệ tái phát. Chúng tôi
yêu cầu bồi thường đó C(n) ≤ D (2k) k là như vậy 2k−1 đó < n ≤ 2k. Sau đó C(n) ≤
D (2k) = 2 k k ≤ 2n log n. Nó vẫn còn để tranh luận bất đẳng thức C(n) ≤ D (2k). Chúng tôi
sử dụng cảm ứng trên k. Cho k = 0, chúng ta có n = 1 và C(1) = 0 = D(1) và yêu cầu bồi thường
chắc chắn giữ. Cho k > 1, chúng tôi quan sát rằng n/2 ≤ n/2 ≤ 2k−1 và hence
C(n) ≤ C (n/2) C (n/2) n − 1 ≤ 2D (2k−1) 2 k − 1 ≤ D (2k).
Điều này hoàn thành bằng chứng chính. Chúng tôi chuyển sang các bằng chứng refined. Chúng tôi chứng minh that
C(n) ≤ n log n − 2
đăng n
1 ≤ n đăng n
bằng quy nạp qua n. Cho n = 1, yêu cầu bồi thường là chắc chắn đúng. Vì vậy, giả sử n > 1. Chúng tôi
distinquish hai trường hợp. Giả định chính mà chúng tôi có 2k−1 < ≤ n/2 n/2 ≤ 2k cho
một số nguyên k. Sau đó đăng nhập n/2 = log n/2 = n k và đăng nhập = k 1 and
hence
C(n) ≤ C (n/2) C (n/2) n − 1
≤
n/2 k − 2k 1
= nk n − 2k 1 1 = n (k 1) − 2k 1 1 = n log n − 2
n/2 k − 2k 1 n − 1
đăng n
1.
nếu không, chúng tôi có n/2 = 2k−1 và n/2 = 2k−1 1 cho một số số nguyên k và
do đó đăng n/2 = k − 1, đăng nhập n/2 = n k và đăng nhập = k 1. Thus
C(n) ≤ C (n/2) C (n/2) n − 1
≤ 2k−1 (k − 1) − 2k−1 1 (2k−1 1) k − 2 k 1 2 k 1 − 1
= (2k 1) k − 2k−1 − 2k−1 1 1
= (2 k 1)(k 1) − 2 k 1 1 = n log n − 2
đăng n
1.
ràng buộc cho thời gian thực hiện có thể là verified bằng cách sử dụng một tương tự lặp lại mối quan hệ.
Mergesort là phương pháp của sự lựa chọn cho phân loại liên kết danh sách và là do đó fre-
quently được sử dụng trong chức năng và hợp lý ngôn ngữ lập trình có danh sách như là của họ
cấu trúc dữ liệu chính. Trong phần 5.3, chúng ta sẽ thấy rằng mergesort về cơ bản là opti-
Mal như xa như số so sánh là có liên quan; do đó, nó cũng là một lựa chọn tốt nếu
so sánh là tốn kém. Khi thực hiện bằng cách sử dụng mảng, mergesort đã quảng cáo-
lợi thế ditional nó suối thông qua bộ nhớ một cách tuần tự. Điều này làm cho
nó efficient trong phân cấp bộ nhớ. Phần 5.7 có nhiều hơn về vấn đề đó. Mergesort là
vẫn không phải là phương pháp thông thường của sự lựa chọn cho một efficient dựa trên mảng thực hiện kể từ
kết hợp không hoạt động tại chỗ. (Nhưng nhìn thấy tập thể dục 88 cho một cách có thể ra.)
106
5 phân loại và lựa chọn
tập thể dục 83. Giải thích làm thế nào để chèn phần tử mới k vào một danh sách được sắp xếp kích thước n trong thời gian
O(k log k n).
84 tập thể dục. Chúng tôi đã thảo luận kết hợp cho danh sách nhưng sử dụng tóm tắt trình tự để de-
scription của mergeSort. Cung cấp cho các chi tiết của mergeSort cho liên kết danh sách.
tập thể dục 85. Thực hiện mergesort trong của bạn yêu thích chức năng lập trình lan-
gauge.
tập thể dục 86. Cung cấp cho một efficient dựa trên mảng thực hiện của mergesort trong fa-
vorite ngôn ngữ lập trình mệnh lệnh. Bên cạnh việc đầu vào mảng đó, phân bổ một aux-
iliary mảng kích thước n ở đầu và sau đó sử dụng các mảng hai để lưu trữ tất cả
Trung cấp kết quả. Bạn có thể cải thiện thời gian chạy chuyển đổi sang loại chèn
cho đầu vào nhỏ? Nếu như vậy, chuyển đổi điểm tối ưu trong việc thực hiện của bạn là gì?
tập thể dục 87. Cách chúng tôi mô tả kết hợp, có ba so sánh cho mỗi vòng lặp
lặp — một phần so sánh và hai kết thúc bài kiểm tra. Phát triển một biến thể
sử dụng gác có nhu cầu chỉ có một kết thúc thử nghiệm. Bạn có thể làm điều đó mà không có phụ thêm
dummy yếu tố để các chuỗi?
tập thể dục 88. Tập thể dục 47 giới thiệu một danh sách của khối đại diện cho chuỗi.
thực hiện kết hợp và mergesort cho cấu trúc dữ liệu này. Trong việc sáp nhập, tái sử dụng làm trống
đầu vào khối cho chuỗi sản lượng. Hãy so sánh các không gian và thời gian efficiency của kết hợp-
sắp xếp cho cấu trúc dữ liệu, danh sách liên kết đồng bằng, và mảng. Chú ý đến liên tục
yếu tố.
đang được dịch, vui lòng đợi..
