root/python/exercise/mergesort2.py

リビジョン 35, 1.5 kB (コミッタ: sgk, コミット時期: 2 年 前)

与えられた引数をいじらないように変更。

  • svn:executable 属性の設定値: *
Line 
1 #!/usr/bin/python
2 # coding:utf-8
3
4 '''マージソート(再帰呼び出しを使わない)
5 練習問題「マージソートを作る」。
6
7 >>> mergeSort((3, 1, 100, 5, 8, 4, 3, 9, 2, 0, 7, 10))
8 [0, 1, 2, 3, 3, 4, 5, 7, 8, 9, 10, 100]
9 >>> mergeSort(())
10 []
11 >>> mergeSort((3,))
12 [3]
13 >>> mergeSort((4,3))
14 [3, 4]
15 >>> mergeSort([7,6])
16 [6, 7]
17 '''
18
19 def mergeSort(arg):
20   '''マージソート
21   タプルまたはリストを与える。
22   リストを返す。
23   '''
24   if len(arg) < 2:
25     # 項目数が1以下なら、そのまま返す。
26     # リストじゃない場合のためにリストに変換。
27     return list(arg)
28
29   # [1, 2, 3] ==> [[1], [2], [3]]
30   sorting = [[x] for x in arg]
31
32   # [[1, 2, 3]]という形になるまで繰り返す。
33   while len(sorting) > 1:
34
35     # リストの長さの半分(端数は切り下げ)まで繰り返す。
36     # 端数が出た場合には右端の1個が処理されないが気にしない。
37     for offset in xrange(len(sorting) / 2):
38
39       # 着目点offsetから2個を取り出して、
40       a = sorting[offset]
41       b = sorting[offset + 1]
42
43       # マージする。
44       r = []
45       while len(a) > 0 and len(b) > 0:
46         if a[0] < b[0]:
47           r.append(a.pop(0))
48         else:
49           r.append(b.pop(0))
50
51       # 取り出した2個の部分を、マージされた物で置き換える。
52       sorting[offset:offset+2] = [r + a + b]
53
54   return sorting[0]
55
56
57 # テスト用。
58 if __name__ == '__main__':
59   import doctest
60   doctest.testmod()
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。