Đệ quy là trực quan hơn vì thế tôi thích giống nhau, ngoại trừ trong một số trường hợp khi tôi muốn tránh một độ sâu ngăn xếp đáng kể (ví dụ: trong khi tiêu thụ một số triển khai đồng nhất định). Trong trường hợp Merge sắp xếp, tuy nhiên phiên bản lặp lại thực sự dễ theo dõi hơn (ít nhất là mã giả).
Tất cả những gì cần thiết là một vòng lặp lồng nhau với vòng lặp bên trong thực hiện các lần hợp nhất trên các cặp phần tử 2^k với vòng lặp bên ngoài chịu trách nhiệm tăng dần k.
Một bước bổ sung cần thiết là hợp nhất bất kỳ nhóm chưa được ghép nối nào với nhóm đã hợp nhất trước đó. Một nhóm chưa được ghép nối sẽ gặp phải nếu số phần tử không phải là một sức mạnh của 2. Một nhóm chưa được ghép nối sẽ luôn ở cuối của lần lặp.
ví dụ: [5, 7, 3, 4, 1, 9] -> [5, 7] [3, 4] [1, 9] -> [3, 4, 5, 7] [1, 9] -> [ 1, 3, 4, 5, 7, 9]
Trong ví dụ trên [1, 9] là một nhóm không có nhóm khác được hợp nhất với ban đầu. Do đó nó được sáp nhập với nhóm trước đó (mà đã được sáp nhập và sắp xếp đã được)
Đây là một thực hiện python:
from MergeSort import merge
def sort(arr):
n = len(arr) - 1
c = 1
start = 0
mid = 0
end = 0
while c <= n:
while end < n:
mid = start + c//2
end = start + c
if (start < n) and (end <= n):
merge(arr, start, mid, end)
start = end + 1
else:
merge(arr, start - c - 1, start-1, n)
c = 2*c + 1
start = 0
mid = 0
end = 0
tôi đã sử dụng chức năng merge từ (recursive) phiên bản thông thường. Trong khi mã trên không phải là thanh lịch nhất, nhưng nó hoạt động và có độ phức tạp tương tự như phiên bản đệ quy.(Tôi đã không kiểm tra kỹ lưỡng nhưng có vẻ như vậy để tôi khỏi trong nháy mắt nhanh)
Dưới đây là một thử nghiệm đơn vị:
def test_merge_sort_iterative(self):
for i in range(1, 100):
length = randint(10, 5000)
data = [randint(1, 10000) for x in range(1, length)]
IterativeMergeSort.sort(data)
issorted = True
i = 0
while (i < len(data) - 1) & issorted:
if data[i] > data[i + 1]:
issorted = False
i += 1
self.assertTrue(issorted, data)
return
Hãy xem xét các câu trả lời ở đây: http://stackoverflow.com/questions/2171517/ implement-a-mergesort-without-using-an-additional-array – Marcin