2017-01-31 4 views
0

私はmergesortアルゴリズムの2つの異なる実装を書いていますが、それを分割する配列の中点を見つけるのに使われる式の違いは1つだけです。Pythonでmergesortの中間点を見つける

最初の実装:(正しく実行)

def mergesort(arr): 
    start = 0 
    end = len(arr) - 1 
    if len(arr) > 1: 
     mid = int(len(arr)/2) 
     left = mergesort(arr[:mid]) 
     right = mergesort(arr[mid:]) 
     return merge(left,right) 
    else: 
     return arr 

def merge(left,right): 
    final = [] 
    while len(left) > 0 or len(right) > 0: 
     if len(left) > 0 and len(right) > 0: 
      if left[0] < right[0]: 
       final.append(left[0]) 
       del left[0] 
      elif right[0] < left[0]: 
       final.append(right[0]) 
       del right[0] 
     elif len(right) > 0: 
      final.extend(right) 
      right = [] 
     elif len(left) > 0: 
      final.extend(left) 
      left = [] 
    return final 


arr = list(map(int,input().split(' '))) 
print ("List before sorting:",arr) 
final = mergesort(arr) 
print ("After sorting:",final) 

第2の実施形態(無限ループに入った):

def mergesort(arr): 
    start = 0 
    end = len(arr) - 1 
    if len(arr) > 1: 
     mid = int(start + (end - start)/2) 
     left = mergesort(arr[:mid]) 
     right = mergesort(arr[mid:]) 
     return merge(left,right) 
    else: 
     return arr 

def merge(left,right): 
    final = [] 
    while len(left) > 0 or len(right) > 0: 
     if len(left) > 0 and len(right) > 0: 
      if left[0] < right[0]: 
       final.append(left[0]) 
       del left[0] 
      elif right[0] < left[0]: 
       final.append(right[0]) 
       del right[0] 
     elif len(right) > 0: 
      final.extend(right) 
      right = [] 
     elif len(left) > 0: 
      final.extend(left) 
      left = [] 
    return final 


arr = list(map(int,input().split(' '))) 
print ("List before sorting:",arr) 
final = mergesort(arr) 
print ("After sorting:",final) 

IはクイックソートALGOの場合に用いられる第2の式を見てきました。問題は、私の目的がアレイを分割すること(クイックソートの場合のように)が無限ループに入る理由です。

私は非常に困惑しており、論理的な結論に至ることはできません。

誰かに問題を投げかけてもらえますか?ありがとうございます。

+0

'arr'に' len(arr)== 2 'があるときに2番目のループが何をするのか自分自身に尋ねてください。 –

+0

私が正しくパトリックに従っているかわかりません。 len(arr)== 2の場合、ループが問題を引き起こします。もう少し詳しいことを教えてください。前もって感謝します。 –

+0

'len(arr)== 2 'の場合、' mergesort'の 'start'は' 0'で 'end'は' len(arr)-1 = 1'です。そして、 'mid'は' int(0 +(0 + 1)/ 2)== 0'です。インデックス '0'で分割しているので、サブリストの1つは長さ '0'で、もう1つは長さ '2'です。あなたは長さ '2'ループの無限ループを持っています –

答えて

0

サブ配列の複数のインスタンスではなく、単一の配列で作業する場合は、2番目の方法を使用する必要があります。実際の別個のサブアレイを使用する代わりに、元のアレイはインデックス範囲を介して論理サブアレイに分割されます。 mergesort関数は、3つのパラメータmergesort(arr、start、end)を呼び出し、呼び出し元はmergesort(arr、0、len(arr))を呼び出します。マージ関数は、merge(arr、start、mid、end)の4つのパラメータをとります。

効率は、1つのパラメータmergesort(arr)を取るエントリ関数を使用して改善することができます。 1つの作業配列tmpを割り当てて内部関数に渡すと、mergesort(arr)の呼び出しはmergesort(arr、tmp、0、len(arr))になります。 mergesort関数は、mergesort(arr、tmp、start、end)です。マージ関数は、merge(arr、tmp、start、mid、end)になります。

関連する問題