プロが教える店舗&オフィスのセキュリティ対策術

問題文:ヒープに新たなデータを挿入する関数insertを作成せよ。空の配列に複数回insertを行うことで
構成したヒープがヒープ条件を満たしていることをcheck_heapを用いることで確認せよ。プロトタイプ宣言は以下とする。
void insert(int val, int a[],int *n);

質問: 
複数回はおいといてとりあえず1回insertしようと思って書いたんですが、ヒープの最後に新しいノードを
作って親より小さければ親の値と交換を繰り返してヒープを完成させようとしてるんですが、1回しか交換されません。
どうすればいいですか?check_heapは最小ヒープ条件が満たされていれば1を満たされていなければ0を返す関数です。
自分のソース
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int check_heap(int a[], int n);
void insert(int val, int a[], int *n);


int main(void) {
int a[11] = {1,13,71,14,15,80,91,24,60,63};
int n;
int i;
int b,c;

srandom(time(NULL));
b = random() % 100 + 1;
n = 10;

insert(b, a, &n);


printf("%d\n", check_heap(a, 11));


for(i = 0; i < 11; i++){

printf("%3d", a[i]);


}




return 0;
}

int check_heap(int a[], int n) {
int i;
int m;
m = (n - 1) / 2;
for(i = 0; i < m; i++)
{
if(a[i] >= a[i * 2 + 1])
{
return 0;
}
if(a[i] >= a[i * 2 + 2]){
return 0;
}
}


if(n % 2 == 0){

if(a[(n - 1)/2] > a[n - 1]){

return 0;
}
}
return 1;

}

void insert(int val, int a[], int *n) {

int temp;


a[*n] = val;


while(a[(*n-1) / 2] >= a[*n]){
temp = a[(*n-1) / 2];
a[(*n-1) / 2] = a[*n];
a[*n] = temp;

}





}

A 回答 (2件)

> 1回しか交換されません。



この↓中で*nを更新していないから(while-loopが一回止まり)じゃないかしら。

void insert(int val, int a[], int *n)
 int temp;
 a[*n] = val;
 while(a[(*n-1) / 2] >= a[*n]){
  temp = a[(*n-1) / 2];
  a[(*n-1) / 2] = a[*n];
  a[*n] = temp;
 }
}
    • good
    • 0

操作しようとしているmain()の配列変数aは、ローカル変数であってヒープではありません。



現状で初期値が設定されているのが10個、配列のサイズが11個なのであと1つの値を入れることは可能ですが…課題の要件は満たさないでしょう。
# というかこの場合のヒープってなんでしょう??

で……

>while(a[(*n-1) / 2] >= a[*n]){
> temp = a[(*n-1) / 2];
> a[(*n-1) / 2] = a[*n];
> a[*n] = temp;
>}
のループでは*nの値(というか、アドレス渡しする必要あるんでしょうか?)は変化していません。
条件が真だったら1回入れ替えが実行され、後は条件から外れるのでループ終了するでしょう。
# 条件が「以上」となっているので、無限ループする可能性もありますが。
# 今回の場合、main()でbが15だったときに時に、a[(*n-1) / 2] >= a[*n]が真になり続けるので無限ループ。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!