Skip to content

Commit 1ead72d

Browse files
committed
uploaded project for mergeSort
note minor change to open file in 'b' (binary) mode when creating random file with lots of values
1 parent be040f7 commit 1ead72d

2 files changed

Lines changed: 214 additions & 0 deletions

File tree

2. O(n log n) Behavior/README.txt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Module 2 O(n log n) Behavior
2+
3+
This module contains the following files
4+
5+
* insertion.py implements InsertionSort
6+
* merge.py implements mergeSort
7+
* project_merge.py implements mergeSort on external file
8+
9+
Also contains compareSortTimes() which compares
10+
performance of mergeSort against Python's internal
11+
sort implementation
12+
13+
To run the project, load 'project_merge.py' and create a file which will be sorted. Do so as follows:
14+
15+
>>> createRandom(100, 'sample-file.txt')
16+
17+
This creates 100 random integers in the range [1,1000] in the given file. If you want to create larger numbers, say:
18+
19+
>>> createRandom(100, 'sample-file.txt', 10000)
20+
21+
which would create numbers in the range [1,10000]
22+
23+
To show the integers in the file, use the 'output' function
24+
25+
>>> output('sample-file.txt')
26+
27+
To sort the external file, say:
28+
29+
>>> mergeSortFile('sample-file.txt')
30+
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# mergesort using mmap
2+
3+
import shutil
4+
import tempfile
5+
import mmap
6+
import os
7+
import random
8+
from time import time
9+
10+
def mergesort (A):
11+
"""public method for using mergesort on array"""
12+
copy = list(A)
13+
mergesort_array (copy, A, 0, len(A))
14+
15+
def mergesort_array(A, result, start, end):
16+
"""mergesort array in memory"""
17+
if end - start < 2:
18+
return
19+
if end - start == 2:
20+
if result[start] > result[start+1]:
21+
result[start],result[start+1] = result[start+1],result[start]
22+
return
23+
24+
mid = (end + start)/2
25+
mergesort_array(result, A, start, mid)
26+
mergesort_array(result, A, mid, end)
27+
28+
# merge A left-and right
29+
i = start
30+
j = mid
31+
idx = start
32+
while idx < end:
33+
if j >= end or (i < mid and A[i] < A[j]):
34+
result[idx] = A[i]
35+
i += 1
36+
else:
37+
result[idx] = A[j]
38+
j += 1
39+
40+
idx += 1
41+
42+
43+
def compareSortTimes():
44+
"""compare sorting algorithms"""
45+
46+
n = 128
47+
while n <= 262144:
48+
timeN = timeM = 0
49+
for t in range(10):
50+
a1 = [random.randint(1,n) for x in range(n)]
51+
a2 = list(a1)
52+
53+
now = time()
54+
a1.sort()
55+
timeN += (time() - now)
56+
57+
now = time()
58+
mergesort(a2)
59+
timeM += (time() - now)
60+
61+
assert a1 == a2
62+
63+
print n, '\t', timeN/10, '\t', timeM/10
64+
n *= 2
65+
66+
def output (src):
67+
"""print numbers in file"""
68+
srcFile = open(src, "a+b")
69+
srcMap = mmap.mmap(srcFile.fileno(), 0)
70+
length = os.stat(src).st_size
71+
72+
while length > 0:
73+
print readInt(srcMap)
74+
length -= 4
75+
srcMap.close()
76+
srcFile.close()
77+
78+
def mergeSortFile (src):
79+
"""external mergesort using mmap"""
80+
81+
length = os.stat(src).st_size
82+
83+
dest = tempfile.NamedTemporaryFile(delete=False)
84+
dest.close()
85+
shutil.copy(src, dest.name)
86+
87+
srcFile = open(src, "a+b")
88+
srcMap = mmap.mmap(srcFile.fileno(), 0)
89+
destFile = open(dest.name, "a+b")
90+
destMap = mmap.mmap(destFile.fileno(), 0)
91+
92+
mergeSortMMap (destMap, srcMap, 0, length)
93+
srcMap.close()
94+
destMap.close()
95+
srcFile.close()
96+
destFile.close()
97+
98+
def readInt(m):
99+
"""read four bytes as int"""
100+
b1 = ord(m.read_byte())
101+
b2 = ord(m.read_byte())
102+
b3 = ord(m.read_byte())
103+
b4 = ord(m.read_byte())
104+
105+
ival= (b1 << 24) + (b2 << 16) + (b3 << 8) + (b4 << 0)
106+
return ival
107+
108+
def writeInt(m, n):
109+
"""write int as four bytes"""
110+
b1 = (n >> 24) & 255
111+
b2 = (n >> 16) & 255
112+
b3 = (n >> 8) & 255
113+
b4 = n & 255
114+
115+
m.write_byte(chr(b1))
116+
m.write_byte(chr(b2))
117+
m.write_byte(chr(b3))
118+
m.write_byte(chr(b4))
119+
120+
def mergeSortMMap(A, result, start, end):
121+
"""recursively mergesort A[start:end] into result"""
122+
123+
if end - start < 8:
124+
return
125+
126+
if end - start == 8:
127+
result.seek(start)
128+
left = readInt(result)
129+
right = readInt(result)
130+
131+
if left > right:
132+
result.seek(start)
133+
writeInt(result, right)
134+
writeInt(result, left)
135+
return
136+
137+
mid = (end + start)/8*4;
138+
mergeSortMMap(result, A, start, mid);
139+
mergeSortMMap(result, A, mid, end);
140+
141+
result.seek(start)
142+
143+
i = start
144+
j = mid
145+
idx = start
146+
while idx < end:
147+
148+
A.seek(i)
149+
Ai = readInt(A)
150+
Aj = 0;
151+
if j < end:
152+
A.seek(j)
153+
Aj = readInt(A)
154+
155+
if j >= end or (i < mid and Ai < Aj):
156+
writeInt(result, Ai)
157+
i += 4
158+
else:
159+
writeInt(result, Aj)
160+
j += 4
161+
162+
idx += 4
163+
164+
def createRandom(n, name, high=1000):
165+
"""Create file containing n random integers with maximum value"""
166+
167+
out = open(name, "wb")
168+
for i in range(n):
169+
val = random.randint(1,high)
170+
171+
out.write(chr((val >> 24) & 255))
172+
out.write(chr((val >> 16) & 255))
173+
out.write(chr((val >> 8) & 255))
174+
out.write(chr(val & 255))
175+
176+
out.close()
177+
178+
"""
179+
Change Log
180+
----------
181+
2014.05.23 createRandom
182+
defect: out = open(name, "w")
183+
fix: out = open(name, "wb")
184+
"""

0 commit comments

Comments
 (0)