4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ストゥージソートをPython3で実装(バブルソート&クイックソート)

Posted at

ストゥージソート(stooge sort)というソートがあるそうです。このソートアルゴリズムはとても__効率の悪い__ソートアルゴリズムらしく、バブルソートより効率が悪いとか。

この記事ではストゥージソートをPython3で実装してみます。


# リストを破壊的にソートする。アルゴリズムは「ストゥージソート」
def stooge_sort(ls):
    stack = [(0, len(ls) - 1)]
    
    while stack:
        i, j = stack.pop()
        if ls[i] > ls[j]: ls[i], ls[j] = ls[j], ls[i]
        
        if j - i + 1 >= 3:
            t = (j - i + 1) // 3
            stack.extend(((i, j - t), (i + t, j), (i, j - t)))

if __name__ == '__main__':
    import random

    ls = list(range(30))
    random.shuffle(ls)

    print(ls)
    stooge_sort(ls)
    print(ls)

# [20, 4, 13, 28, 12, 0, 17, 19, 22, 21, 5, 23, 3, 27, 14, 2, 29, 11, 24, 7, 15, 9, 25, 6, 26, 18, 8, 1, 10, 16]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]

確かにちゃんとソートできているようですね。 工夫(?)としては再帰ではなく、繰り返しで実装している点ですが……効率のわるいアルゴリズムに対して、効率よく実装する意味はあるのか(´・ω・`)

次に効率ですが、効率の悪い「バブルソート」効率のいい「クイックソート」をそれぞれ実装し、1000個の要素を持つリストをソートする時間を計測してみたいと思います。

# リストを破壊的にソートする。アルゴリズムは「ストゥージソート」
def stooge_sort(ls):
    stack = [(0, len(ls) - 1)]
    
    while stack:
        i, j = stack.pop()
        if ls[i] > ls[j]: ls[i], ls[j] = ls[j], ls[i]
        
        if j - i + 1 >= 3:
            t = (j - i + 1) // 3
            stack.extend(((i, j - t), (i + t, j), (i, j - t)))


# リストを破壊的にソートする。アルゴリズムは「バブルソート」
def bubble_sort(ls):
    t = len(ls)

    for i in range(t - 1):
        for j in range(i + 1, t):
            if ls[i] > ls[j]: ls[i], ls[j] = ls[j], ls[i]


# リストを破壊的にソートする。アルゴリズムは「クイックソート」
def quick_sort(ls):
    stack = [(0, len(ls) - 1)]

    while stack:
        left, right = stack.pop()
        if left >= right: continue

        pivot = ls[left + (right - left) // 2]
        i, j = left, right
        while True:
            while ls[i] < pivot: i += 1
            while ls[j] > pivot: j -= 1

            if i >= j: break
            
            ls[i], ls[j] = ls[j], ls[i]
            i, j = i + 1, j - 1

        stack.extend(((j + 1, right), (left, i - 1)))

if __name__ == '__main__':
    import random, copy, time

    ls = list(range(1000))
    random.shuffle(ls)
    
    bubble_ls = copy.deepcopy(ls)
    bubble_start = time.time()
    bubble_sort(bubble_ls)
    bubble_time = time.time() - bubble_start

    quick_ls = copy.deepcopy(ls)
    quick_start = time.time()
    quick_sort(quick_ls)
    quick_time = time.time() - quick_start

    stooge_ls = copy.deepcopy(ls)
    stooge_start = time.time()
    stooge_sort(stooge_ls)
    stooge_time = time.time() - stooge_start

    print("bubble : {}".format(bubble_time))
    print("quick  : {}".format(quick_time))
    print("stooge : {}".format(stooge_time))

    # bubble : 0.0938718318939209
    # quick  : 0.0
    # stooge : 33.47836709022522

遅い ((((´・ω・`))))

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?