クラスでは、ソートアルゴリズムを実行しています。それらについて説明し、擬似コードを記述すると、それらをうまく理解できますが、実際のコードを書くのに問題があります。
これはPythonでの私の試みです:
mylist = [12, 5, 13, 8, 9, 65]
def bubble(badList):
length = len(badList) - 1
unsorted = True
while unsorted:
for element in range(0,length):
unsorted = False
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
print badList
else:
unsorted = True
print bubble(mylist)
さて、これは(私が知る限り)正しくソートされますが、終了すると無限にループします。
このコードを修正して、関数が適切に終了し、任意の(合理的な)サイズのリストを正しくソートできるようにするにはどうすればよいですか?
追伸関数に実際に印刷物を入れてはならず、リターンを返すべきだと知っていますが、コードがまだ実際に機能しないため、まだ印刷していません。
スクリプトが現在動作しない理由を説明するために、変数の名前をunsorted
からsorted
に変更します。
最初は、リストはまだソートされていません。もちろん、sorted
をFalse
に設定します。
while
ループを開始するとすぐに、リストが既にソートされていると想定します。考え方は次のとおりです。正しい順序にない2つの要素が見つかったらすぐに、sorted
をFalse
に戻します。 sorted
は、True
のままです。間違った順序の要素がなかった場合のみ。
sorted = False # We haven't started sorting yet
while not sorted:
sorted = True # Assume the list is now sorted
for element in range(0, length):
if badList[element] > badList[element + 1]:
sorted = False # We found two elements in the wrong order
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
# We went through the whole list. At this point, if there were no elements
# in the wrong order, sorted is still True. Otherwise, it's false, and the
# while loop executes again.
また、コードをより効率的にしたり読みやすくしたりするのに役立つ小さな問題もあります。
for
ループでは、変数element
を使用します。技術的には、element
は要素ではありません。リストインデックスを表す数字です。また、かなり長いです。これらの場合、「インデックス」にi
などの一時変数名を使用します。
for i in range(0, length):
range
コマンドは、1つの引数(stop
という名前)のみを取ることもできます。その場合、0からその引数までのすべての整数のリストを取得します。
for i in range(length):
Pythonスタイルガイド では、変数にアンダースコアを付けて小文字で名前を付けることを推奨しています。これは、このような小さなスクリプトの非常にマイナーな選択です。 Pythonコードが最もよく似ているものに慣れるだけです。
def bubble(bad_list):
2つの変数の値を交換するには、それらをTuple割り当てとして記述します。右側は、タプルとして評価され(たとえば、(badList[i+1], badList[i])
は(3, 5)
)、左側の2つの変数に割り当てられます((badList[i], badList[i+1])
)。
bad_list[i], bad_list[i+1] = bad_list[i+1], bad_list[i]
それをすべてまとめると、これが得られます:
my_list = [12, 5, 13, 8, 9, 65]
def bubble(bad_list):
length = len(bad_list) - 1
sorted = False
while not sorted:
sorted = True
for i in range(length):
if bad_list[i] > bad_list[i+1]:
sorted = False
bad_list[i], bad_list[i+1] = bad_list[i+1], bad_list[i]
bubble(my_list)
print my_list
(ところで、私はあなたのprintステートメントも削除しました。)
バブルソートの目標は、各ラウンドの下部にある重いアイテムを移動し、ライターアイテムアップ。要素を比較する内側のループでは、ターンごとにリスト全体を繰り返す必要はありません。 最も重いはすでに最後に配置されています。 swapped変数は追加のチェックなので、リストがソートされたことをマークし、不必要な計算を続行しないようにすることができます。
def bubble(badList):
length = len(badList)
for i in range(0,length):
swapped = False
for element in range(0, length-i-1):
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
swapped = True
if not swapped: break
return badList
バージョン1、修正済み:
def bubble(badList):
length = len(badList) - 1
unsorted = True
while unsorted:
unsorted = False
for element in range(0,length):
#unsorted = False
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
unsorted = True
#print badList
#else:
#unsorted = True
return badList
これは、負の意味の変数名を使用するときに起こることであり、それらの値を反転する必要があります。次の方が理解しやすいでしょう。
sorted = False
while not sorted:
...
一方、アルゴリズムのロジックは少しずれています。 forループ中に2つの要素がスワップされたかどうかを確認する必要があります。ここに私がそれを書く方法があります:
def bubble(values):
length = len(values) - 1
sorted = False
while not sorted:
sorted = True
for element in range(0,length):
if values[element] > values[element + 1]:
hold = values[element + 1]
values[element + 1] = values[element]
values[element] = hold
sorted = False
return values
Unsorted変数の使用は間違っています。 2つの要素を交換したかどうかを通知する変数が必要です。それを行った場合は、ループを終了できます。それ以外の場合は、再度ループする必要があります。ここで取得した内容を修正するには、ifケースの本文に「unsorted = false」を入力します。 elseケースを削除します。 for
ループの前に「unsorted = true」を配置します。
def bubble_sort(l):
for passes_left in range(len(l)-1, 0, -1):
for index in range(passes_left):
if l[index] < l[index + 1]:
l[index], l[index + 1] = l[index + 1], l[index]
return l
#非常に単純な関数で、2番目の配列の問題空間を減らすことで(明らかに)最適化できます。しかし、同じO(n ^ 2)の複雑さ。
def bubble(arr):
l = len(arr)
for a in range(l):
for b in range(l-1):
if (arr[a] < arr[b]):
arr[a], arr[b] = arr[b], arr[a]
return arr
より簡単な例:
a = len(alist)-1
while a > 0:
for b in range(0,a):
#compare with the adjacent element
if alist[b]>=alist[b+1]:
#swap both elements
alist[b], alist[b+1] = alist[b+1], alist[b]
a-=1
これは、0からa(基本的に、そのラウンドのすべてのソートされていない要素)の要素を取り、その要素を隣接する要素と比較し、隣接する要素よりも大きい場合はスワップします。ラウンドの終わりに、最後の要素がソートされ、すべての要素がソートされるまで、プロセスはそれなしで再び実行されます。
sort
が真であるかどうかの条件は必要ありません。
このアルゴリズムは、スワッピング時にのみ数字の位置を考慮するため、数字を繰り返しても影響はありません。
PS。この質問が投稿されてから非常に長い時間が経ちましたが、このアイデアを共有したかっただけです。
def bubble_sort(l):
exchanged = True
iteration = 0
n = len(l)
while(exchanged):
iteration += 1
exchanged = False
# Move the largest element to the end of the list
for i in range(n-1):
if l[i] > l[i+1]:
exchanged = True
l[i], l[i+1] = l[i+1], l[i]
n -= 1 # Largest element already towards the end
print 'Iterations: %s' %(iteration)
return l
私は新鮮な初心者で、昨日Pythonについて読み始めました。あなたの例に触発されて、私は80タイスタイルでもっと何かを作成しましたが、それでもちょっとうまくいきます
lista1 = [12, 5, 13, 8, 9, 65]
i=0
while i < len(lista1)-1:
if lista1[i] > lista1[i+1]:
x = lista1[i]
lista1[i] = lista1[i+1]
lista1[i+1] = x
i=0
continue
else:
i+=1
print(lista1)
元のアルゴリズムの問題は、リスト内の数字がこれよりも小さい場合、正しいソート位置に移動できないことです。プログラムは、数値が最後までソートされるように、毎回最初に戻る必要があります。
コードを単純化したので、リストに関係なく、また繰り返し番号がある場合でも、すべての番号リストで機能するようになりました。ここにコードがあります
mylist = [9, 8, 5, 4, 12, 1, 7, 5, 2]
print mylist
def bubble(badList):
length = len(badList) - 1
element = 0
while element < length:
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
element = 0
print badList
else:
element = element + 1
print bubble(mylist)
def bubble_sort(a):
t = 0
sorted = False # sorted = False because we have not began to sort
while not sorted:
sorted = True # Assume sorted = True first, it will switch only there is any change
for key in range(1,len(a)):
if a[key-1] > a[key]:
sorted = False
t = a[key-1]; a[key-1] = a[key]; a[key] = t;
print a
def bubbleSort(alist):
if len(alist) <= 1:
return alist
for i in range(0,len(alist)):
print "i is :%d",i
for j in range(0,i):
print "j is:%d",j
print "alist[i] is :%d, alist[j] is :%d"%(alist[i],alist[j])
if alist[i] > alist[j]:
alist[i],alist[j] = alist[j],alist[i]
return alist
alist = [54,26,93,17,77,31,44,55,20、-23、-34,16,11,11,11]
print bubbleSort(alist)
そこにはいくつかのエラーがあります。 1つ目は長さで、2つ目は未分類(McWafflestixによると)の使用です。リストを印刷する場合は、おそらくリストを返すこともできます。
mylist = [12, 5, 13, 8, 9, 65]
def bubble(badList):
length = len(badList) - 2
unsorted = True
while unsorted:
for element in range(0,length):
unsorted = False
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
print badList
unsorted = True
return badList
print bubble(mylist)
eta:そのとおりです。上記は地獄のようなバグです。いくつかの例を介してテストを行わないのは悪いことです。
def bubble2(badList):
swapped = True
length = len(badList) - 2
while swapped:
swapped = False
for i in range(0, length):
if badList[i] > badList[i + 1]:
# swap
hold = badList[i + 1]
badList[i + 1] = badList[i]
badList[i] = hold
swapped = True
return badList
def bubble_sort(li):
l = len(li)
tmp = None
sorted_l = sorted(li)
while (li != sorted_l):
for ele in range(0,l-1):
if li[ele] > li[ele+1]:
tmp = li[ele+1]
li[ele+1] = li [ele]
li[ele] = tmp
return li
def bubbleSort ( arr ):
swapped = True
length = len ( arr )
j = 0
while swapped:
swapped = False
j += 1
for i in range ( length - j ):
if arr [ i ] > arr [ i + 1 ]:
# swap
tmp = arr [ i ]
arr [ i ] = arr [ i + 1]
arr [ i + 1 ] = tmp
swapped = True
if __== '__main__':
# test list
a = [ 67, 45, 39, -1, -5, -44 ];
print ( a )
bubbleSort ( a )
print ( a )
def bubblesort(array):
for i in range(len(array)-1):
for j in range(len(array)-1-i):
if array[j] > array[j+1]:
array[j], array[j+1] = array[j+1], array[j]
return(array)
print(bubblesort([3,1,6,2,5,4]))
def bubble_sort(l):
for i in range(len(l) -1):
for j in range(len(l)-i-1):
if l[j] > l[j+1]:
l[j],l[j+1] = l[j+1], l[j]
return l
def merge_bubble(arr):
k = len(arr)
while k>2:
for i in range(0,k-1):
for j in range(0,k-1):
if arr[j] > arr[j+1]:
arr[j],arr[j+1] = arr[j+1],arr[j]
return arr
break
else:
if arr[0] > arr[1]:
arr[0],arr[1] = arr[1],arr[0]
return arr
これを試して
a = int(input("Enter Limit"))
val = []
for z in range(0,a):
b = int(input("Enter Number in List"))
val.append(b)
for y in range(0,len(val)):
for x in range(0,len(val)-1):
if val[x]>val[x+1]:
t = val[x]
val[x] = val[x+1]
val[x+1] = t
print(val)
これは9年後にあなたを助けるかもしれないならidk ...その単純なバブルソートプログラム
l=[1,6,3,7,5,9,8,2,4,10]
for i in range(1,len(l)):
for j in range (i+1,len(l)):
if l[i]>l[j]:
l[i],l[j]=l[j],l[i]
The-furyとMartin Coteの回答により、無限ループの問題は修正されましたが、私のコードはまだ正しく動作しません(より大きなリストの場合、正しくソートされません)。 unsorted
変数を捨てて、代わりにカウンターを使用しました。
def bubble(badList):
length = len(badList) - 1
n = 0
while n < len(badList):
for element in range(0,length):
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
n = 0
else:
n += 1
return badList
if __== '__main__':
mylist = [90, 10, 2, 76, 17, 66, 57, 23, 57, 99]
print bubble(mylist)
誰かがコメントで私のコードを改善する方法についてのポインタを提供できれば、それは大歓迎です。
私のソリューションを共有したい:
def bubble_sort(list_):
for i in range(len(list_)):
for j in range(i, len(list_)):
if a[i] > a[j]:
a[i], a[j] = a[j], a[i]
return list_
テスト例:
a = [8,1,2,4,1,3,5,1,5,6,1,8]
bubble_sort(a)
結果:
[1, 1, 1, 1, 2, 3, 4, 5, 5, 6, 8, 8]