前提
Cで https://daeudaeu.com/heap-sort/ のサイトを参考にヒープソートのプログラムを作っています。
アルゴリズムに問題はないと思うのですが、途中の書き方で予期せぬ無限ループに陥ってしまいました。
問題が起きているのは、サイトのrenoveHeap関数のwhileの中です。
※該当のソースコードは全てのコードを貼ると長くなるので、一部分だけ切り取っています。なのでサイトを見ながらの方がわかりやすいかと思います。お手数ですが、
宜しくお願いします。
実現したいこと
- なぜこのような動作になるのかが知りたい
発生している問題
デバッグで挙動を見たところ、leftとrightの大小比較が終わったタイミングで必ず、コメント"// 両方存在する"の下の行 if(array[left] > array[right])を経由してからwhileの先頭に戻っていることが確認できました。
問題は実行途中で if(array[left] > array[right]) に飛んでしまい、なぜか無限ループに陥ってしまうことです。(しかもswap関数を呼ぶときに毎回起きるのではなく、あるタイミングで起きる)
該当のソースコード
C
1while(1) { 2 left = GetLeft(parent); 3 right = GetRight(parent); 4 5 // if(leftもrightも存在するか? (配列長の端に来てるとleftのみor両方ない場合がある) ) 6 if (left < size && right < size) { 7 // 両方存在する 8 if (array[left] > array[right]) { // leftの方がrightより大きい 9 if (array[left] > array[parent]) { // さらにleftがparentより大きい 10 swap(&array[left], &array[parent]); 11 parent = left; 12 } 13 // elseの場合は何もしない 14 } 15 else if (array[right] > array[left]) { // rightの方がleftより大きい 16 if (array[right] > array[parent]) { // さらにrightがparentより大きい 17 swap(&array[right], &array[parent]); 18 parent = right; 19 } 20 } 21 } 22 23 // leftのみ存在 24 else if (left <= size) { // leftの方がparentより大きい 25 if (left > parent) { 26 swap(&array[left], &array[parent]); 27 parent = left; 28 } 29 } 30 31 // 両方ない 32 else { break; }
試したこと
該当箇所(removeHeapのwhile内)をサイトの通りに書くと正常に動きました。
C
1while(1){ 2 left = GetLeft(parent); 3 right = GetRight(parent); 4 5 // if(leftもrightも存在するか? (配列長の端に来てるとleftのみor両方ない場合がある) ) 6 if (left < length && right < length) { 7 // 両方存在 8 if (array[left] > array[right]) { // leftの方がrightより大きい 9 large = left; 10 } 11 else { large = right; } 12 } 13 // leftのみ存在 14 else if (left <= length) { // leftの方がparentより大きい 15 large = left; 16 } 17 // 両方ない 18 else { break; } 19 20 // leftとrightの大きい方と,parentとの大小比較と入れ替え 21 if (array[large] <= array[parent]) { break;} 22 else { swap(&array[large], &array[parent]); } 23 24 // 根ノードはデータを交換した子ノードの位置に移動する 25 parent = large; 26}
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー