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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Q&A

解決済

2回答

1398閲覧

ヒープソートの実装について

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

0グッド

1クリップ

投稿2021/05/13 11:29

編集2021/05/13 12:24

ヒープソートのプログラムの作成をしてます。ファイルからデータN個読み込み、ソートして出力するというものです。(昇順)
データNは、
88,176,137,60,198,198,51,137,115,10,187,25,71,26,25,79,37,133,156,126
の20個で、下記のコードを実行すると、
26,10,79,25,25,37,71,85,115,126,133,137,137,156,176,187,198,198
となってしまいます前半部分が上手くソートできてないようなのですが、コードのどの部分が原因なのかわからないため、おしえていただきたいです。

#include <stdio.h> #include <stdlib.h> #include <string.h> /* 文字列関数を扱えるようにする */ #define maxN 50 int parent(int i); void heapsort(int*H, int *A, int n); void buildheap(int *H, int *A, int n); void insert(int *H, int i, int *a); void upheapsort(int *H, int i); void downheapsort(int *H, int i); int main(void) { int Data[maxN]; /* 数値を格納する配列は Data */ int Heap[maxN]; /* ヒープを表す補助配列 */ int i,N=0; /* N やループで用いる int 型変数 */ char fname[128]; FILE *fp; /* ファイル名の変数など必要なものを宣言 */ printf("input filename: "); /* ファイル名の入力を要求 */ fgets(fname, sizeof(fname), stdin); fname[strlen(fname)-1] = '\0'; fflush(stdin); fp = fopen(fname, "r"); /* ファイルを読み込みモードで開く */ fscanf(fp, "%d", &N); /* N をファイルから読み込む */ if (N > maxN){ printf("N is too large, setting N = %d\n", maxN); N = maxN; /* N が max Nを超えるときは警告をした上で */ } /* N =maxN に設定する */ for (i=0; i<N; i++){ fscanf(fp, "%d", &Data[i]); } fclose(fp); /* 開いたファイルを閉じる */ for (i=0; i<N; i++){ printf("% d", Data[i]); /* ソート前の数値の出力 */ } printf("\n"); heapsort(Heap, Data, N); /* ヒープソートを呼ぶ */ for (i=0; i<N; i++){ printf("% d", Data[i]); /* ソート後の数値の出力 */ } printf("\n"); return (0); } void heapsort(int*H, int *A, int n) { int i; buildheap(H, A, n); for(i=1; i<n; i++) { A[n-i] = H[0]; H[0] = H[n-i]; downheapsort(H, n-i-1); } A[0] = H[0]; } void buildheap(int *H, int *A, int n) { int i; for(i=0; i<n; i++) { insert(H, i, A); } } void insert(int *H, int i, int *a) { H[i] = a[i]; upheapsort(H,i); /* 入れ替え */ } void upheapsort(int *H, int i) { int u; int p; int j=0; int tmp[j]; u = i; p = parent(i); /*親の設定*/ while(u > 0 && H[p] < H[u]) { tmp[j] = H[p]; H[p] = H[u]; H[u] = tmp[j]; u = p; p = parent(p); } } int parent(int i) { int parent; parent = (i-1)/2; return parent; } void downheapsort(int *H, int i) { int l,r; int u = 0; int j=0; int tmp[j]; int a = 1; while(a == 1) { if(2*u+1 < i) { l = 2 * u + 1; } else { l = u; } if(2*u+2 < i) { r = 2 * u + 2; } else { r = u; } if(H[u] < H[r] || H[u] < H[r]) { if(H[l] < H[r]) { tmp[j] = H[u]; H[u] = H[r]; H[r] = tmp[j]; u = r; } else { tmp[j] = H[u]; H[u] = H[l]; H[l] = tmp[j]; u = l; } } else { a = 0; } } }

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

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

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

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

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

y_waiwai

2021/05/13 11:35

このままではコードが見づらいので、質門を編集し、<code>ボタンで、出てくる’’’の枠の中にコードを貼り付けてください
退会済みユーザー

退会済みユーザー

2021/05/13 11:38

ご指摘ありがとうございます。
actorbug

2021/05/13 11:42

buildheap と downheapsort の定義は?
退会済みユーザー

退会済みユーザー

2021/05/13 11:55

buildheapでは格納してあるデータをヒープ性を満たすように調節してます。 downheapsortでは大きい値(根)をデータに格納し直した際に、崩れたヒープ性を満たすように調節してます。
actorbug

2021/05/13 12:10

いや、説明が聞きたいわけではなくて、プログラムの中に buildheap の宣言しかなくて定義がないから このままだとコンパイルできません、という意味です。
退会済みユーザー

退会済みユーザー

2021/05/13 12:20

申し訳ないです。その部分のコードが抜けてしまっていました。
guest

回答2

0

解決済みになっていますが、どのようにして解決したのですか?

次の修正ではないのですか?

diff

1- downheapsort(H, n-i-1); 2+ downheapsort(H, n-i);

int j = 0; int tmp[j]; も変ですが。

投稿2021/05/13 12:54

kazuma-s

総合スコア8224

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

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

actorbug

2021/05/13 13:05

確かに、この修正を入れないと、「4,2,3,1」のような入力がソートできません。見落としてました。
guest

0

ベストアンサー

とりあえず、ぱっと見でおかしそうなところを指摘しておきます。

C

1 int j=0; 2 int tmp[j];

tmpという配列のサイズが0になってますが、これは意図したことでしょうか。

C

1if(H[u] < H[r] || H[u] < H[r])

||の前後が全く同じ式ですが、これは意図したことでしょうか。

投稿2021/05/13 12:32

actorbug

総合スコア2431

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

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

退会済みユーザー

退会済みユーザー

2021/05/13 12:42

そこの部分の凡ミスでした… ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問