-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f8122bb
commit a01833b
Showing
3 changed files
with
137 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
def merge_sort(S): | ||
"""Sort (in-place) elements of Python list S using merge-sort""" | ||
n = len(S) | ||
if n < 2: | ||
return | ||
|
||
mid = n // 2 | ||
S1 = S[0:mid] | ||
S2 = S[mid:n] | ||
|
||
merge_sort(S1) | ||
merge_sort(S2) | ||
|
||
merge(S1, S2, S) | ||
|
||
|
||
def merge(S1, S2, S): | ||
i = j = 0 | ||
while i + j < len(S): | ||
if j == len(S2) or (i < len(S1) and S1[i] < S2[j]): | ||
S[i + j] = S1[i] | ||
i += 1 | ||
else: | ||
S[i + j] = S2[j] | ||
j += 1 | ||
|
||
|
||
if __name__ == "__main__": | ||
l = [4, 5, 6, 34, 2, 7, 8, 9, 0] | ||
merge_sort(l) | ||
print(l) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from ..chap7 import LinkedQueue | ||
|
||
|
||
def merge(S1: LinkedQueue, S2: LinkedQueue, S: LinkedQueue): | ||
while not S1.is_empty() and not S2.is_empty(): | ||
if S1.first() < S2.first(): | ||
S.enqueue(S1.dequeue()) | ||
else: | ||
S.enqueue(S2.dequeue()) | ||
|
||
while not S1.is_empty(): | ||
S.enqueue(S1.dequeue()) | ||
|
||
while not S2.is_empty(): | ||
S.enqueue(S2.dequeue()) | ||
|
||
|
||
def merge_sort(S: LinkedQueue): | ||
n = len(S) | ||
if n < 2: | ||
return | ||
|
||
S1 = LinkedQueue() | ||
S2 = LinkedQueue() | ||
|
||
while len(S1) < n // 2: | ||
S1.enqueue(S.dequeue()) | ||
|
||
while not S.is_empty(): | ||
S2.enqueue(S.dequeue()) | ||
|
||
merge_sort(S1) | ||
merge_sort(S2) | ||
|
||
merge(S1, S2, S) | ||
|
||
|
||
if __name__ == "__main__": | ||
l1 = LinkedQueue() | ||
l2 = LinkedQueue() | ||
|
||
l1.enqueue(1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
""" | ||
The main idea is to perform merge-sort bottom-up, performing the merges level | ||
by level going up the merge-sort tree. | ||
Given an input array of elements, we begin by merging every | ||
successive pair of elements into sorted runs of length two. | ||
We merge these runs into runs of length four, merge these new runs into runs of | ||
length eight, and so on, until the array is sorted. | ||
To keep the space usage reasonable, we deploy a second array that stores the | ||
merged runs (swapping input and output arrays after each iteration). | ||
""" | ||
|
||
import math | ||
|
||
|
||
def merge(src, result, start, inc): | ||
"""Merge src[start:start+inc] and src[start+inc:start+2*inc] into result""" | ||
# boundary for run 1 | ||
end1 = start + inc | ||
# boundary for run 2 | ||
end2 = min(start + 2*inc, len(src)) | ||
|
||
# index into run 1, run 2, result | ||
x, y, z = start, start + inc, start | ||
|
||
while x < end1 and y < end2: | ||
if src[x] < src[y]: | ||
# copy from run 1 and increment | ||
result[z] = src[x] | ||
x += 1 | ||
else: | ||
# copy from run 2 and increment | ||
result[z] = src[y] | ||
y += 1 | ||
# increment z to reflect new result | ||
z += 1 | ||
|
||
if x < end1: | ||
# copy remainder of run 1 to output | ||
result[z:end2] = src[x:end1] | ||
elif y < end2: | ||
# copy remainder of run 2 to output | ||
result[z:end2] = src[y:end2] | ||
|
||
|
||
def merge_sort(S): | ||
n = len(S) | ||
logn = math.ceil(math.log(n, 2)) | ||
# make temp storage for dest | ||
src, dest = S, [None] * n | ||
|
||
# pass i creates all runs of length 2i | ||
for i in (2**k for k in range(logn)): | ||
# each pass merges two length i runs | ||
for j in range(0, n, 2*i): | ||
merge(src, dest, j, i) | ||
# reverse roles of list | ||
src, dest = dest, src | ||
|
||
if S is not src: | ||
# additional copy to get results to S | ||
S[0:n] = src[0:n] |