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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

459閲覧

挿入ソート、バブルソート、選択ソートの手順が理解できません・・・

cand

総合スコア65

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/04/15 04:49

挿入ソート、バブルソート、選択ソートの手順が理解できません。
どなたか教えてください。
ソースコードも提示していただけると幸いです。
よろしくお願いいたします。

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

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

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

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

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

guest

回答3

0

動画見るのが一番いいと思います。

投稿2018/04/15 04:54

mpyw

総合スコア5223

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

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

cand

2018/04/15 04:56

手順はわかるのですが、ソースコードで表すのができません。 よろしくお願いします。
mpyw

2018/04/15 04:58

ググればいくらでも出てくるので,課題等で急ぎであれば拾ってきてください。但し既に指摘されている通り,自分の力にしたいのであればある程度自分で考えないと意味がありません。
mpyw

2018/04/15 04:59

「手順」を計画した上で,それを「コード」に変換していく作業を「プログラミング」といいます。ここすっ飛ばしてたらプログラミングの力は身につかないですよ。
mpyw

2018/04/15 05:00

いきなりC言語のソースコードに落とし込むのが難しければ, 〜の間ループ  もし〜なら   …する  それ以外なら   …する のような日本語を使って書いてからそれをC言語に変換してもいいし。
mpyw

2018/04/15 08:14

↑の日本語でとりあえず書いてみるフェーズもできないのであれば,その状態を「手順はわかる」とは言いません。漠然とした概念を具体的な手順に書き出すことをやってみてから言ってください。
guest

0

ベストアンサー

こんにちは、

まず初めに

他の方もおっしゃっていますが本当は自分である程度は考える必要があります。
もちろん人から教わるのも一つの勉強ですが、自分で考え理解することで初めて自分のものになります。
プログラミングは頭で考えるのが約80%、考えたことをコードに落とし込むのが約20%といわれています。
今回は、私が実際書いたコードを使って説明しますが、ひとつひとつ理解して進んでください。

1.挿入ソート

全てのデータの中で0番目からi番目までのうちi番目より大きい数字があったら,その2つを入れ替えるソートです。
最初はi = 0 その次はi = 1と増え それぞれ0からiまでの中で処理をするので、2重for文を使いましょう。

C++

1for(i = 0; i < MAX_NUMBER; i++){ 2 for(j = 0; j <= i; j++){ 3 if(data[i] < data[j]){ 4 tmp = data[i]; //2つのデータを入れ替える 5 data[i] = data[j]; 6 data[j] = tmp; 7 } 8 } 9}

その都度、2つのデータを比べ右のほうが大きかったら、2つのデータを入れ替えます。
<サンプルコード>

C

1#include <stdio.h> 2#include <stdlib.h> 3 4#define MAX_NUMBER 10 5 6int main(void){ 7 8 int data[MAX_NUMBER] = {8,4,5,7,9,1,13,2,15,6}; 9 int i,j; 10 int tmp; 11 for(i = 0; i < MAX_NUMBER; i++){ 12 for(j = 0; j <= i; j++){ 13 if(data[i] < data[j]){ 14 tmp = data[i]; 15 data[i] = data[j]; 16 data[j] = tmp; 17 } 18 } 19 } 20 for(i = 0; i < MAX_NUMBER; i++){ 21 printf("%d ",data[i]); 22 } 23 return 0; 24} 25

2.バブルソート
3つの中では一番わかりやすいと思います。
隣り合った2つのデータを比べ、右のほうが大きかったら入れ替えます。
ここで、重要なのは一番右には最も大きいデータが来るということです。(最大となるものから右に寄る)
そして、その次は、一番右以外でまた入れ替え作業をします。
データがN個のとき最初は,0番目からN - 1番目
その次は0番目からN - 2番目... となるのでここの2重for文は、

C++

1for(i = N - 1; i >= 0; i--){ 2 for(j = 0; j < i; j++){ 3 } 4}

となります。実際の処理内容は先ほどと あまり変わらないので、説明は省略します。
<サンプルコード>

C++

1#include <stdio.h> 2 3#define MAX_NUMBER 10 4 5int main(void) 6{ 7 int data[MAX_NUMBER] = {8,4,5,7,9,1,13,2,15,6}; 8 int i,j; 9 int tmp; 10 for(i = MAX_NUMBER - 1; i >= 0; i--){ 11 for(j = 0; j < i; j++){ 12 if(data[j] > data[j + 1]){ 13 tmp = data[j]; 14 data[j] = data[j + 1]; 15 data[j + 1] = tmp; 16 } 17 } 18 } 19 for(i = 0; i < MAX_NUMBER; i++){ 20 printf("%d ",data[i]); 21 } 22 return 0; 23}

3.選択ソート
これは説明も実際のコードも少し複雑になります。
最初は0番目だけ、その次は0番目から1番目...のように
0番目からi番目までの中で最小値を求め、その最小値を一番左にあるデータと入れ替えます。
ここで重要なのでは,最小値だけではなく、最小値がもともとあった場所を記憶する必要があるということです。

<サンプルコード>

C++

1#include <stdio.h> 2 3#define MAX_NUMBER 10 4 5int main(void) 6{ 7 int data[MAX_NUMBER] = {8,4,5,7,9,1,13,2,15,6}; 8 int i,j; 9 int tmp,tmp_posi; 10 int tmp2; 11 int position = 0; 12 for(i = 0; i < MAX_NUMBER; i++){ 13 tmp = data[i]; 14 for(j = i; j < MAX_NUMBER; j++){ 15 if(tmp > data[j]){ 16 tmp = data[j]; 17 tmp_posi = j; 18 } 19 } 20 tmp2 = data[position]; 21 data[position] = tmp; 22 data[tmp_posi] = tmp2; 23 position++; 24 } 25 for(i = 0; i < MAX_NUMBER; i++){ 26 printf("%d ",data[i]); 27 } 28 return 0; 29}

最後に

最初にも言いましたが、やはり自分で考えることが大切です。
2重for文の場合、中でどんな処理が行われているか最初はわからなくて混乱するかもしれません。
「i = 0 の時、jが0からMAX_NUMBERまで動くとこのような処理が行われる」など、
実際に、配列の番号のところに数字を代入して、確認することで理解が深まるでしょう。
地道な作業かもしれませんが、プログラミングを学ぶ上で大切なことだと思います。

投稿2018/04/15 13:07

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2018/04/15 13:08 編集

もし、間違えているところや気になった点があったら指摘してください。
退会済みユーザー

退会済みユーザー

2018/04/15 13:10

他のソートだとシェルソートやクイックソートなどがありますが、やはり一番わかりやすいのは バブルソートかもしれません。
退会済みユーザー

退会済みユーザー

2018/04/15 13:11 編集

ちなみに私が主に使っているソートは選択ソートです。
mkgrei

2018/04/15 22:23

素朴な疑問ですが、選択ソートはそれほど速くありません。 標準ライブラリのクイックソートはあえて使用しないということでしょうか?
episteme

2018/04/15 23:52 編集

要素数に依りますよ。数十程度なら単純なソートの方がよっぽど速いし。 とはいえ、わざわざ自前で書くことはないです僕は。 # あと、安定なソートが条件ならクイックソートは使えない。
mkgrei

2018/04/15 23:55

コメントをありがとうございます。 要素数が少なく、反復して行われる場合選択ソートの方が速い可能性があるということですね。 選択ソートも安定ソートではなかった記憶だったので…
episteme

2018/04/15 23:58

> 選択ソートも安定ソートではなかった記憶だったので… 実装次第じゃないかしら。 最も小さい要素が複数あったとき、先頭寄りの要素を採用すれば安定すんじゃね?
mkgrei

2018/04/16 06:08

[1,3,3,2] の時、3が入れ替わってしまうような… 何かアルゴリズムを勘違いしてたら申し訳ありません。
episteme

2018/04/16 06:14

あー...そかそか。 「"配列をもいっこ用意して、そっちにソート結果を転記する"なら安定する」です。ゴメン。
退会済みユーザー

退会済みユーザー

2018/04/16 06:15

if文で左が右より大きいときだけ入れ替える評価をしているので大丈夫だと思います。
episteme

2018/04/16 06:15

”単純選択”改め”単純挿入”ですね安定するのは。配列が対象では出番なさげ。
episteme

2018/04/16 06:17

> if文で左が右より大きいときだけ... "バブルでのおはなし"ですよね?
退会済みユーザー

退会済みユーザー

2018/04/16 06:22

if文で左が右より大きいときだけ... はいこれはバブルでのお話です。 しかし、3つのどのソートをやっても最終結果は同じですよね?
mkgrei

2018/04/16 09:24

挿入ソートとバブルソートが安定で、選択ソートは非安定かと。 なので、選択ソートだけ結果が異なる可能性があります。 比較演算子が定義されていればソートができるので、「イコール」でも「同じもの」とは限りません。 そして、出現順序が重要となる場合、安定ソートを採用する必要があるという流れかと。
cand

2018/04/30 00:53

ありがとうございます
guest

0

ググれば出てくるはずですが。
Qiita - 「ソート」を極める! 〜 なぜソートを学ぶのか 〜

また、当たり前の話ですが、理解した上で書かないとなんの得も無いということをお忘れなく。

投稿2018/04/15 04:53

LouiS0616

総合スコア35660

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問