質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

7回答

2537閲覧

Pythonでの再帰関数を使用したクイックソートがエラーメッセージ無しで停止した場合の対処法を教えていただきたいです

python__student

総合スコア1

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/11/04 00:08

編集2021/11/04 00:16

前提・実現したいこと

Pythonの勉強のため再帰関数を使用したクイックソートを行いたいです。
実行環境は下記の通りです。
OS : Windows10(64bit), Ubuntu系のディストリビューション
Python : 3.10.0, 3.7.3

教えていただきたいこと

プログラムの停止する原因と対処法
エラーメッセージが出力されない原因
この問題が分かる方がいらっしゃれば、ご教示をお願いいたします。

発生している問題・エラーメッセージ

Pythonを用いてクイックソートのプログラムを作成し、ソートする要素の数を多くしたところ、エラーメッセージを表示しないでプログラムが終了しました。

エラーメッセージはありません

該当のソースコード

Python

1import random 2import time 3import sys 4import threading 5 6#再起する回数の上限を設定 7sys.setrecursionlimit(2100000000) 8#スタックの容量を設定 9threading.stack_size(255*1024*1024) 10 11#並び替えをするリスト内の要素数を設定するための変数 12N = 0 13#生成する乱数の大きさの範囲を設定するための変数 14random_range = 9999999 15 16#乱数リストを生成する関数 17def make_ramdom_list(): 18 global random_list 19 random_list = [] 20 for i in range(N): 21 random_list = random_list + [random.randrange(random_range)] 22 23#クイックソートのメインプログラム 24def quick_sort(sort_ramdom_list, first, last): 25 if first < last: 26 pivot = sort_ramdom_list[int((first + last) / 2)] 27 i = first 28 j = last 29 30 while sort_ramdom_list[i] < pivot: 31 i += 1 32 while sort_ramdom_list[j] > pivot: 33 j -= 1 34 if i <= j: 35 swap_number = sort_ramdom_list[j] 36 sort_ramdom_list[j] = sort_ramdom_list[i] 37 sort_ramdom_list[i] = swap_number 38 i += 1 39 j -= 1 40 41 quick_sort(sort_ramdom_list, first, j) 42 quick_sort(sort_ramdom_list, i, last) 43 44#ソートする要素の数を設定 45N = 200000 46print("N:" + str(N)) 47make_ramdom_list() 48start = time.time() 49quick_sort(random_list, 0, N - 1) 50#ソートされたリストを表示する(要素が多いと表示する量が多くなりますのでコメントアウトします。) 51#print(random_list) 52print("time:" + str(time.time() - start))

試したこと

再帰する回数の上限を設定
スタックの容量を設定

補足情報(FW/ツールのバージョンなど)

当方の実行環境ではリストの要素の数が数万程度であれば実行可能なのですが、20万程度になるとエラーメッセージが無くプログラムが停止します。

プログラム実行時に使用するメモリーの量を確認したところ、最大で13メガバイト程度でした。

同様の結果を出力するマージソートのプログラムを実行したところ問題なく実行されました。

参考にしたサイトでは再帰関数がタイムアウトする可能があるとの記述があったのですが、技術不足の為に理解することができませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TakaiY

2021/11/04 01:08

ソースコードの quick_sort 関数内のwhileループあたりのインデントがおかしくありませんか? これだと、ソートできないと思うのですが。
python__student

2021/11/04 01:36

返答ありがとうございます。 インデントがおかしいというのは「i += 1」の部分でしょうか? 現状、このプログラムで45行目の「N=200000」を「N=10000」程度の値を代入すると、 ソートする要素の数が代入値になり実行することができました。
TakaiY

2021/11/04 02:00

すみません。こちらがちょっと勘違いしていたようです。
python__student

2021/11/04 02:20

わかりました。 不明な点があれば、ご質問ください。
guest

回答7

0

一般論で言いますと、再起関数というのはスタックを消費するためにあまり深くは実行できません。
なので、対処法、というなら、再帰を使わない処理に書き変える、ということになろうかと思います

投稿2021/11/04 02:24

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

python__student

2021/11/04 02:56

返答ありがとうございます。 現在、プログラムの学習のために再帰を用いてプログラムを行っています。 ですので、方針としては再帰的なプログラムで実行したいと考えています。 それらを踏まえて、スタックの使用可能容量と使用容量を調べると、設定したスタックの容量に届かない程度しか使用していませんでした。 よろしければ、この問題を一緒に解決していただけないでしょうか。
y_waiwai

2021/11/04 02:59

まあ、スタックサイズを設定で増やして実行できるようにするってのも一つの手ですが、根本的な解決じゃないですね なにを持って解決とするか、ですが。
python__student

2021/11/04 03:26

解決とするのは、20万程度の大きい要素の数でも実行できるクイックソートのプログラムの製作です。 そのための条件としては再起関数の使用です。 また、同様に再起関数を使用するマージソートという方法でプログラムを製作し実行したところ、正常に動作しました。そのプログラムではクイックソートのプログラムと同じように大きなリストを使う他に、マージという操作を行うためのリストもあります。 先述の状況からスタックの使用量に問題があるのかもわからい状況です。
guest

0

プログラムの停止する原因と対処法
エラーメッセージが出力されない原因

こちらの Windows 10 環境では quick_sort() の呼び出し深さが 2672 ぐらいで終わります。
pivot 値より小さい値と大きい値に振り分けが終わらないうちに再帰呼び出しになるため深く呼び出す状況となり、たぶんスタックオーバーフローになっていると思います。
ご提示の quick_sort ベースで quick sort にすると次のようになると思います。

Python

1def quick_sort(sort_ramdom_list, first, last): 2 if first < last: 3 pivot = sort_ramdom_list[(first + last) // 2] 4 i = first 5 j = last 6 while True: 7 while sort_ramdom_list[i] < pivot: 8 i += 1 9 while sort_ramdom_list[j] > pivot: 10 j -= 1 11 if i >= j: 12 break 13 sort_ramdom_list[i], sort_ramdom_list[j] = sort_ramdom_list[j], sort_ramdom_list[i] 14 i += 1 15 j -= 1 16 17 quick_sort(sort_ramdom_list, first, j) 18 quick_sort(sort_ramdom_list, j + 1, last)

できれば計算量が O(n^2) になることがないよう

Python

1def median(a, b, c): 2 ret = a 3 if a >= b >= c or a <= b <= c: ret = b 4 if b >= c >= a or b <= c <= a: ret = c 5 return ret 6 7def quick_sort(sort_ramdom_list, first, last): 8 ... 9 #pivot = sort_ramdom_list[int((first + last) / 2)] 10 val = sort_ramdom_list[(first + last) // 2] 11 pivot = median(sort_ramdom_list[first], val, sort_ramdom_list[last])

としておきたいですね。
そして list の生成は高速化しましょう。

Python

1#def make_ramdom_list(): 2# global random_list 3# random_list = [] 4# for i in range(N): 5# random_list = random_list + [random.randrange(random_range)] 6def make_ramdom_list(start, end, num): 7 return [random.randrange(start, end) for _ in range(num)] 8 9#make_ramdom_list() 10random_list = make_ramdom_list(0, random_range, N)

投稿2021/11/05 11:28

lehshell

総合スコア1156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

python__student

2021/11/06 00:51

lehshellさん 回答ありがとうございます。 問題原因の解説がわかりやすかったです。また、添付していただいたソースコードは高速で驚きました。 添付していただいたプログラムのようなコードを書けるようPythonについて勉強します。
guest

0

ベストアンサー

make_random_list を高速化し、quick_sort を正しく実装してみました。

python

1import random 2import time 3 4N = 200000 5random_range = 9999999 6 7def make_ramdom_list(): 8 global random_list 9 random_list = [0] * N 10 for i in range(N): 11 random_list[i] = random.randrange(random_range) 12 13def quick_sort(a, first, last): 14 if first < last: 15 pivot = a[last] 16 i = first 17 for j in range(first, last): 18 if a[j] <= pivot: 19 a[i], a[j] = a[j], a[i] 20 i += 1 21 a[i], a[last] = a[last], a[i] 22 quick_sort(a, first, i-1) 23 quick_sort(a, i+1, last) 24 25print("N:" + str(N)) 26make_ramdom_list() 27print(random_list[:8]) 28start = time.time() 29quick_sort(random_list, 0, N - 1) 30print("time:" + str(time.time() - start)) 31print(random_list[:8])

ソート前後のデータを先頭 8個だけ表示しています。

投稿2021/11/05 06:18

編集2021/11/05 08:03
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

python__student

2021/11/06 00:10

kazuma-sさん コードの添付ありがとうございます。 ランダムリストの作成やクイックソートが高速化され驚きました。 すべてを再帰的に行おうとして、低速かつ使用スレッド容量が膨大になっていることを改めて理解しました。 こちらで、プログラムを勉強して改善してみます。
guest

0

問題

  1. スタックオーバーフローで落ちている(推測)
  2. クイックソートではない
  3. スタックの設定が出来ていない

1. スタックオーバーフローで落ちている(推測)

何も表示されないのはおそらくWindowsだからだと思いますが、スタックオーバーフローで落ちています。
Windowsでコマンドプロンプトから実行している場合、実行終了時に

bat

1echo %ERRORLEVEL%

とすれば0以外のプロセス終了コードを確認することが出来ます。-1073741571(C00000FD)であればスタックオーバーフローです。

Unix系のOSであればセグメンテーション違反で検出され、大抵のシェルでは処理後にエラー表示があると思います。

2. クイックソートではない

既にご指摘があるとおり、クイックソートではありません。本来のクイックソートはリスト中の全値を走査し、pivot以下のグループ(A)とpivotより大きいグループ(B)に分け、(A)→pivot→(B)となる順に並べた後、(A)内と(B)内をそれぞれ同様に処理していく方法です。

現状のコードはpivotはあるものの1回しかスワップをせずに重複する範囲をさらに再帰呼び出ししているため、バブルソートより効率の悪いソートになっています。

またスワップ1回につき2度再帰呼び出しをするコードなのでスタックを大量に消費しています。ただのクイックソートであればここまで極端にスタックを消費することはありません。ただし正しいクイックソートでも、並び順によっては再帰呼び出しのバブルソートと同じくらいスタックを消費するので、入力が限定されないケースを再帰呼び出しでは実装しません。

まずクイックソートを学びなおしてください。

3. スタックの設定が出来ていない

python

1import threading 2threading.stack_size(255*1024*1024)

では自分で起動するスレッドのスタック設定は出来ても、メインスレッドの設定は出来ません。
メインスレッドの設定をしたければ以下のようにしてください。

python

1from resource import * 2setrlimit(RLIMIT_STACK, (255 * 1024 * 1024, -1))

回答

プログラムの停止する原因と対処法

原因

スタックの無駄遣いによるスタックオーバーフロー(推測)

対処法

まずは正しくクイックソートを実装してください。
余力があれば再帰呼び出しをやめてください。

エラーメッセージが出力されない原因

スタックオーバーフローだからです(推測)。再帰呼び出しの上限を自分で書き換えて、足りないスタックで動かしたためpython実行環境が落ちています。

投稿2021/11/05 04:07

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

python__student

2021/11/05 15:43

dameoさん プログラム停止の調査方法やクイックソートでない理由、スタックのメインスレッドの設定方法など、詳細に記述していただきありがとうございます。 大変わかりやすく、他の回答者さんの方の説明と合わせて、かなり理解できたと思います。 Windows10やraspbianでプログラムを実行してみたところ両者ともにエラーの出力がなかったため原因がわかりませんでしが、セグメンテーション違反を示す情報が得て正確な状況を理解できました。 クイックソートについてとプログラムが異常動作した場合のセグメンテーション違反などのOSの動作についてあたらめて学んできます。
guest

0

手元の環境で、ある操作を行ってから問題のスクリプトを実行してみました。

bash

1$ lsb_release -ir 2Distributor ID: Ubuntu 3Release: 21.04 4 5# デフォルトのスタックサイズは 8 Mib 6$ ulimit -a | grep stack 7stack size (kbytes, -s) 8192 8 9# スタックサイズを 512 KiB に変更 10$ ulimit -s 512 11 12# 実行 13$ python quick.py 14N:200000 15Segmentation fault (core dumped) # 短時間で発生 16 17# gdb による解析 18$ gdb /usr/bin/python core 19 : 20 21Core was generated by `python quick.py'. 22Program terminated with signal SIGSEGV, Segmentation fault. 23#0 0x0000000000515e42 in _PyEval_EvalFrameDefault ()

スクリプト内ではスタックサイズを 255 MiB に設定していますが、少なくとも Linux OS ではシステム側の設定(最近のデフォルトサイズは 8 MiB)が優先されます。

python

1#スタックの容量を設定 2threading.stack_size(255*1024*1024)

プログラムの停止する原因と対処法

Linux OS と同様に Windows OS でもスタックサイズの上限が設定されているのではないかと思います。その値を変更することができるのかどうかは私には分かりませんけれども。

また、末尾再帰に関しては Tail Call Optimization Decorator がありますが、古い話なので効果の程は不明です。

エラーメッセージが出力されない原因

分かりません。

投稿2021/11/04 18:37

編集2021/11/04 18:40
melian

総合スコア20655

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

python__student

2021/11/05 01:19

melianさん 回答ありがとうございます。 提供していただいた情報のOSでのデフォルトの設定は盲点でした。 こちらで、設定を変更する方法を調べ検討します。
guest

0

コメントをしたので、回答もしておきます。

アルゴリズムがクイックソートでない

ftlobw さんの指摘の通り、この処理はクイックソートにはなっていません。

  • リストの真ん中をピボットにする。
  • 右(小さい)から順に見ていって、最初のピボットより小さい値が出てくるところをiとする。
  • 左(大きい)から順に見ていって、最初のピボットより大きい値が出てくるところをiとする。
  • iとjの場所にある値を入れ替える。
  • 小さい方からjまでで同じ処理をする
  • 大きい方からiもでで同じ処理をする。

となっています。これはクイックソートのアルゴリズムではありません。

クイックソートは

  • リストの真ん中をピボットにする。
  • ピボットより左にある、ピボットより大きい値を全て右に移す。
  • ピボットより右にある、ピボットより小さい値を全て左に移す。
  • ピボットより左をソートしたもの + ピボットの値 + ピボットより右をソートしたもの が結果

ざっとという処理になるはずです。

再帰処理で多数のデータをソートするのは現実的ではありません。

クイックソートは再帰で表現するとすっきり書けますので、再帰処理の理解にはよい例だと思いますが、そのロジックで多数のデータをソートするのは現実的ではありません。

大きなデータをクイックソートでソートしたいのであれば、再帰を使わない憑肩で実装すべきです。

投稿2021/11/04 07:17

TakaiY

総合スコア13790

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

python__student

2021/11/04 08:16

回答ありがとうございます。 再起処理を使用した処理の現実性については理解しました。 しかし、クイックソートの条件について、製作したプログラムの、どの動作が条件を満たさないのかがわかりませんでした。 当方の認識としては、指摘していただいた動作を再起処理により繰り返すことによって、条件を満たしていると考えています。 お手数ですが、補足する解説をお願いできますでしょうか。
TakaiY

2021/11/04 09:07

アルゴリズムについては、回答に書いたとおり、提示されたソースのアルゴリズムとクイックソートのアルゴリズムが異なります。 クイックソートは、言葉で書けば、ピボット値を決めて、それより大きなものと小さなものに分けて、それぞれをソートしていくという方式です。提示のコードがそのような処理をしているようには見えません。
python__student

2021/11/04 23:51

TakaiYさん 解説ありがとうございます。 なんとなくですが、理解できたと思います ひとまず、新しくプログラムを作成する方法で検討しようと思います。
guest

0

質問者さんのコメントを受けての追記

(コメントに書いてもらったプログラムはインデントが崩れていて読めないので、すみませんが試していません)
試しにWikipediaの記事にあったクイックソートを実行した場合の途中経過は以下の通りです。
(pivotの選択は、質問者さんの実装と同じにしてあります)

0~9の範囲で pivot: 3 を選択しているところまでは一緒ですが、
その後のpartition処理でpivot未満の数字が一気に左に寄っているのが分かると思います。

text

1before: [1, 7, 5, 4, 3, 8, 9, 2, 6, 0] 2first: 0, last: 9, pivot: 3 3after: [1, 0, 2, 3, 4, 8, 9, 5, 6, 7] 4<以下省略>

何をもってクイックソートと言うのかは、コンピュータサイエンスを専攻したわけではないので自信をもって回答はできないのですが、
Wikipediaの記事に書いてある「ピボットの選択:適当な値(ピボット(英語版)という)を境界値として選択する」を基準にすれば質問者さんの元々の実装は、
再帰を使っているか? → Yes
クイックソートか? → No
だと思います。

python

1from typing import Any, Callable, MutableSequence 2 3# 分割関数 4# 配列の指定範囲をピボットに従って分割する 5# 6# @param seq - 分割する配列 7# @param keyFn - 配列要素のキー値を計算する関数 8# @param first - 分割範囲の最初のインデックス 9# @param last - 分割範囲の最後のインデックス 10# @returns 分割点のインデックス 11def partition(seq: MutableSequence[Any], keyFn: Callable[[Any], Any], first: int, last: int): 12 pivot = seq[int((first + last) / 2)] 13 print(f'first: {first}, last: {last}, pivot: {pivot}') 14 while True: 15 while keyFn(seq[first]) < pivot: 16 first += 1 17 while pivot < keyFn(seq[last]): 18 last -= 1 19 if first >= last: 20 return last + 1 21 seq[first], seq[last] = seq[last], seq[first] 22 first += 1 23 last -= 1 24 25# クイックソート 26# 27# @param seq - ソートする配列 28# @param keyFn - 配列要素のキー値を計算する関数 29def quicksort(seq: MutableSequence[Any], keyFn: Callable[[Any], Any]): 30 def quicksortImpl(seq: MutableSequence, keyFn: Callable[[Any], int], first: int, last: int): 31 global cnt 32 while first < last: 33 cnt += 1 34 print('before:', seq) 35 p = partition(seq, keyFn, first, last) 36 print('after:', seq, end='\n\n') 37 if (p - first) < (last - p): 38 quicksortImpl(seq, keyFn, first, p - 1) 39 first = p 40 else: 41 quicksortImpl(seq, keyFn, p, last) 42 last = p - 1 43 quicksortImpl(seq, keyFn, 0, len(seq) - 1) 44 45 46cnt = 0 47lst = [1, 7, 5, 4, 3, 8, 9, 2, 6, 0] * 1 48quicksort(lst, lambda x: x) 49 50print('=' * 30) 51print(cnt, len(lst)) 52print(lst)

以下は以前の回答です。

pivotを決めた後、quick_sort()を再帰呼び出しするまでの処理が怪しいです。

試しにソートするデータのサイズを変更してquick_sort()の呼び出し回数を確認したところ、
サイズ50で2000回、サイズ100で7.5万回、150で231万回 でした。
このペースだと再帰呼び出しの回数やスタック容量を多少増やしても、
データサイズが大きくなるとスグに破綻すると思います。

添付プログラムのように、最初に [1, 7, 5, 4, 3, 8, 9, 2, 6, 0] というデータを与えて
quick_sort()内でリストの並べ替え状況を確認するコードを埋め込んでみると以下のような結果になります。

これは、ピボットを境界値としてリストをピボット未満(左)とそれ以外(右)に値を分割していくクイックソートではなくて、値を1つづつ入れ替えていくような挙動になっているのではないかと思います。
Wikipediaの記事などを見て、実装を見直してみてはどうでしょうか。

text

1before: [1, 7, 5, 4, 3, 8, 9, 2, 6, 0] 2first: 0, last: 9, pivot: 3 3after: [1, 0, 5, 4, 3, 8, 9, 2, 6, 7] 4 5before: [1, 0, 5, 4, 3, 8, 9, 2, 6, 7] 6first: 0, last: 8, pivot: 3 7after: [1, 0, 2, 4, 3, 8, 9, 5, 6, 7] 8 9before: [1, 0, 2, 4, 3, 8, 9, 5, 6, 7] 10first: 0, last: 6, pivot: 4 11after: [1, 0, 2, 3, 4, 8, 9, 5, 6, 7] 12 13before: [1, 0, 2, 3, 4, 8, 9, 5, 6, 7] 14first: 0, last: 3, pivot: 0 15after: [0, 1, 2, 3, 4, 8, 9, 5, 6, 7] 16 17<以下省略>

python

1#クイックソートのメインプログラム 2def quick_sort(sort_ramdom_list, first, last): 3 global cnt 4 if first < last: 5 cnt += 1 6 print('before:', sort_ramdom_list) 7 8 pivot = sort_ramdom_list[int((first + last) / 2)] 9 i = first 10 j = last 11 12 while sort_ramdom_list[i] < pivot: 13 i += 1 14 while sort_ramdom_list[j] > pivot: 15 j -= 1 16 if i <= j: 17 swap_number = sort_ramdom_list[j] 18 sort_ramdom_list[j] = sort_ramdom_list[i] 19 sort_ramdom_list[i] = swap_number 20 i += 1 21 j -= 1 22 23 print(f'first: {first}, last: {last}, pivot: {pivot}') 24 print('after:', sort_ramdom_list, end='\n\n') 25 26 quick_sort(sort_ramdom_list, first, j) 27 quick_sort(sort_ramdom_list, i, last) 28 29cnt = 0 30lst = [1, 7, 5, 4, 3, 8, 9, 2, 6, 0] * 1 31quick_sort(lst, 0, len(lst) - 1) 32 33print('=' * 30) 34print(cnt, len(lst)) 35print(lst)

投稿2021/11/04 04:35

編集2021/11/04 08:38
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

python__student

2021/11/04 07:41

返答とプログラムの添付、ありがとうございます。 「クイックソートではなく」とのことですが、指定していただいたリンクを確認したところ、クイックソートの動作をしているように見えました。 当方が知識不足のため、具体的にどういった動作がクイックソートの動作でなかったのか、お教えしていただけないでしょうか。 当方がクイックソートであると判断した理由としては、下記の添付していただいたプログラムを加筆したプログラムと結果の抜粋したものを見ていただくと、「cnt」が3と4の時に正常に「first」と「last」の範囲をソートしています。 他にも、「cnt」が5と6の時の「local cnt」の値が減っていることから再帰的に処理していると思います。 言葉足らずで申し訳ありません。 ```Python #クイックソートのメインプログラム def quick_sort(sort_ramdom_list, first, last, local_cnt): global cnt if first < last: cnt += 1 local_cnt += 1 print('before:', sort_ramdom_list) pivot = sort_ramdom_list[int((first + last) / 2)] i = first j = last while sort_ramdom_list[i] < pivot: i += 1 while sort_ramdom_list[j] > pivot: j -= 1 if i <= j: swap_number = sort_ramdom_list[j] sort_ramdom_list[j] = sort_ramdom_list[i] sort_ramdom_list[i] = swap_number i += 1 j -= 1 print('after:', sort_ramdom_list) print(f'cnt: {cnt}, local cnt: {local_cnt}') print(f'first: {first}, last: {last}, i: {i}, j: {j}, pivot point: {int((first + last) / 2)}', end='\n\n') print("call_section_1") quick_sort(sort_ramdom_list, first, j, local_cnt) print("call_section_2") quick_sort(sort_ramdom_list, i, last, local_cnt) cnt = local_cnt = 0 lst = [1, 7, 5, 4, 3, 8, 9, 2, 6, 0] * 1 quick_sort(lst, 0, len(lst) - 1, local_cnt) print('=' * 30) print(cnt, len(lst)) print(lst) ``` ```出力結果の一部抜粋 call_section_1 before: [1, 0, 2, 4, 3, 8, 9, 5, 6, 7] after: [1, 0, 2, 3, 4, 8, 9, 5, 6, 7] cnt: 3, local cnt: 3 first: 0, last: 6, i: 4, j: 3, pivot point: 3 call_section_1 before: [1, 0, 2, 3, 4, 8, 9, 5, 6, 7] after: [0, 1, 2, 3, 4, 8, 9, 5, 6, 7] cnt: 4, local cnt: 4 first: 0, last: 3, i: 1, j: 0, pivot point: 1 call_section_1 call_section_2 before: [0, 1, 2, 3, 4, 8, 9, 5, 6, 7] after: [0, 1, 2, 3, 4, 8, 9, 5, 6, 7] cnt: 5, local cnt: 5 first: 1, last: 3, i: 3, j: 1, pivot point: 2 call_section_1 call_section_2 call_section_2 before: [0, 1, 2, 3, 4, 8, 9, 5, 6, 7] after: [0, 1, 2, 3, 4, 8, 9, 5, 6, 7] cnt: 6, local cnt: 4 first: 4, last: 6, i: 6, j: 4, pivot point: 5 ```
python__student

2021/11/05 00:04

ftlobwさん 追加のコメントありがとうございます。 プログラムがクイックソートでない理由について、少しかもしれないですが理解できたと思います。 新しく添付していただいたプログラムを参考にして、プログラムを製作することを検討してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問