def comp(a, b): if a > b: return 1 elif a < b: return -1 else: return 0 # 配列を、pivotIndex の値で分割する。 # pivotIndex の値より小さい値は前、 # pivotIndex の値より大きい値は後ろに移動 def partition(arr, comp_func, left, right, pivotIndex): # pivot の値を最後尾に移動 pivot = arr[pivotIndex] tmp = arr[right] arr[right] = pivot arr[pivotIndex] = tmp # pivot より小さい値を前に持っていく store = left for i in range(left, right): if comp_func(arr[i], pivot) <= 0: tmp = arr[i] arr[i] = arr[store] arr[store] = tmp store += 1 # pivot を配置 tmp = arr[store] arr[store] = pivot arr[right] = tmp return store # 適当 def selectPivotIndex(left, right): return right # K 番目の値を取得する。 # 返却値はインデックスだが arr が変化した後のインデックスなので # 元の配列でどこにあったか、といったような情報ではない。 # あくまで値のみ。 # 結果として K 番目の値で配列が分割されている。 def selectKth(arr, comp_func, k, left, right): # 適当に pivot を選択 pivotIndex = selectPivotIndex(left, right) # pivot で分割 pivotIndex = partition(arr, comp_func, left, right, pivotIndex) # pivot が K 番目だったら終了。 if left + k == pivotIndex: return pivotIndex # pivot が K よりも大きければ、前方の配列から再度探す。 elif left + k < pivotIndex: return selectKth(arr, comp_func, k, left, pivotIndex - 1) # pivot が K よりも小さければ、後方の配列から再度探す。 else: return selectKth(arr, comp_func, (left + k) - pivotIndex - 1, pivotIndex + 1, right) def medianSort(arr, comp_func, left, right): # 配列のサイズが 1 であれば終了 if right <= left: return mid = (right - left) + 1 / 2 # 配列を中央値で再帰的に分割 selectKth(arr, comp_func, mid, left, right) medianSort(arr, comp_func, left, left + mid - 1) medianSort(arr, comp_func, left + mid + 1, right) a = [1,5,2,7,9,32,6,87,9,21,6,43,556,14,69] medianSort(a, comp, 0, len(a) - 1) print a
▼
2012年11月2日金曜日
algorithm - Median Sort
クイックソートの下準備的な知識になるらしい。
0 件のコメント:
コメントを投稿