1+ '''
2+ Created on May 8, 2012
3+
4+ @author: matt
5+
6+ Example merge sort
7+ '''
8+ from random import Random
9+
10+
11+ def merge_sort (left , right = None ):
12+
13+ if right == None :
14+ mid = len (left ) / 2
15+ return merge_sort (left [:mid ], left [mid :])
16+
17+ # handle no length
18+ if not left : return right
19+ if not right : return left
20+
21+ # handle lengths of 1
22+ if len (left ) == len (right ) == 1 :
23+ if left [0 ] > right [0 ]:
24+ # swap
25+ return [right [0 ], left [0 ]]
26+ # left and right sorted in order and length of 1 each so return as new array
27+ return [left [0 ], right [0 ]]
28+
29+ # split left and right and sort those
30+ mid = (len (left ) / 2 ) or 1
31+ left = merge_sort (left [:mid ], left [mid :])
32+
33+ # split right and sort those
34+ mid = (len (right ) / 2 ) or 1
35+ right = merge_sort (right [:mid ], right [mid :])
36+
37+ # merge
38+ A = []
39+ for i in xrange (len (left ) + len (right )):
40+ l = None
41+ r = None
42+
43+ if len (left ):
44+ l = left [0 ]
45+ else :
46+ # no more left so append all of right
47+ A .extend (right )
48+ return A
49+
50+ if len (right ):
51+ r = right [0 ]
52+ else :
53+ # no more right
54+ A .extend (left )
55+ return A
56+
57+ # if left is smaller then put it next, otherwise r
58+ if l <= r :
59+ A .append (l )
60+ del left [0 ]
61+ else :
62+ A .append (r )
63+ del right [0 ]
64+ return A
65+
66+
67+ import unittest
68+
69+
70+ class Test (unittest .TestCase ):
71+
72+
73+ def testSimple (self ):
74+ self .assertEqual ([1 , 2 , 3 ], merge_sort ([3 , 2 , 1 ]))
75+ self .assertEqual ([1 , 2 , 3 ], merge_sort ([1 , 3 , 2 ]))
76+
77+ self .assertEqual ([1 , 3 , 4 , 4 , 5 , 5 , 7 , 8 ], merge_sort ([4 , 5 , 1 , 7 , 8 , 4 , 3 , 5 ]))
78+
79+ def testRandom10 (self ):
80+ random = Random ()
81+ pop = range (10 ) + range (10 )
82+ A = random .sample (pop , 10 )
83+ self .assertEquals (sorted (A ), merge_sort (A ))
84+
85+ def testRandom32767 (self ):
86+ random = Random ()
87+ max = 32767
88+ pop = range (max ) + range (max )
89+ A = random .sample (pop , max )
90+ self .assertEquals (sorted (A ), merge_sort (A ))
91+
92+
93+ if __name__ == "__main__" :
94+ #import sys;sys.argv = ['', 'Test.testSimple']
95+ unittest .main ()
0 commit comments