• 締切済み

c 言語 B tree

C言語で B-treeを実装するプログラムを書きました。 まだtreeに挿入する関数しか書いておりませんが。。 まず空の根を作ってからそこにどんどん要素を挿入していくのですが、どうも要素が 挿入されていないように思えます。 どこがいけないのか分かる方いらっしゃいませんか? よろしくお願いします。 #include <stdio.h> #define T 10 struct b_tree{ int key[2*T-1]; struct b_tree *node[2*T]; int size; int leaf;//この節点が葉であったら1とする }; void BTreeCreate(void); void BTreeSplitChild(struct b_tree x,int i,struct b_tree y); void BTreeInsert(struct b_tree t,int k); void BTreeInsertNonfull(struct b_tree x,int k); void PrintBtree(struct b_tree x); struct b_tree root; int main (int argc, const char * argv[]) { // insert code here... /*int t;*/ char command; int key; BTreeCreate(); /*scanf("%d",&t);*/ while (1) { scanf("%c %d",&command,&key); if (command=='E') break; if(command=='I') BTreeInsert(root,key);//木にkeyを挿入 } PrintBtree(root); //木を表示 return 0; } void BTreeCreate(void){//空のB-木の生成 struct b_tree x; x.leaf=1; x.size=0; root=x; } void BTreeSplitChild(struct b_tree x,int i,struct b_tree y){ /*B-木における節点の分割をする節点xのi番目の枝の先にある節点yが飽和であった 場合にyをyの中央値で分ける。yの中央値はxの新たなkeyとなりxの枝数は1つ増える*/ int j; struct b_tree z; z.leaf=y.leaf; //zが葉であるかどうかはyが葉であるかどうかに依る z.size=T-1; //また新しくできるxの子zは最小数のkey(T-1)を持たせる for (j=1; j<= T-1; j++) { z.key[j]=y.key[j+1]; //yの中央値よりおおきい値(T-1個)をzに渡す } if(y.leaf==0){ //またyが個をもつ場合は枝もzに渡す for (j=1; j<=T; j++) z.node[j]=y.node[T+j]; } y.size=T-1; //そしてyのサイズも中央値とzに渡した分小さくなる for (j= x.size+1; j>=i+1; j--) { //xにyの中央値を渡すのでx枝の右半分を1つずつ右へずらす x.node[j+1]=x.node[j]; } x.node[i+1]=&z; //i+1番目の枝に新たな子zのポインタを与える for (j=x.size; j>=i; j--) { //値も右へずらす x.key[j+1]=x.key[j]; } x.key[i]=y.key[T]; //xのi番目の値をyの中央値とする。 x.size=x.size+1; //xは1サイズup } void BTreeInsert(struct b_tree t,int k){ int Tsub=T; //条件部にTが使えなかったのでTsubに退避 struct b_tree r,s; r=t; if (r.size == Tsub) { /*根が飽和だった場合を考える新たな親を必要とするため それをsとする。するとsは葉ではなく、sizeは0, そして元々の根rのポインタを与える*/ s.leaf=0; s.size=0; s.node[1]=&r; root=s; BTreeSplitChild(s,1,r); BTreeInsertNonfull(r,k); } else { BTreeInsertNonfull(r,k); } } void BTreeInsertNonfull(struct b_tree x,int k){ /*未飽和の節点xにkを挿入しようと考える。*/ int i; int Tsub=T; if (x.leaf==1) { /*もし、xが葉であれば大小関係を考えて挿入。その際他のkey を右へ1つずつずらす。またxのサイズを1up*/ while (i>=1 && k<x.key[i]) { x.key[i+1]=x.key[i]; i--; } x.key[i+1]=k; x.size++; } else { /*もしxが葉でなければどこの枝をたどればいいのか考える*/ while (i>=1 && k<x.key[i]) { i--; } i++; if ((*x.node[i]).size == 2*Tsub-1) { /*たどる枝の先が飽和であった場合分割する*/ BTreeSplitChild(x, i, *x.node[i]); if (k > x.key[i]) { i++; } } BTreeInsertNonfull(*x.node[i],k);//枝をたどる } } void PrintBtree(struct b_tree x){ printf("abc"); printf("%d",x.leaf);//実行するとleafが1のままなので、数が挿入されていない? int i,l;        if(x.leaf==1){ for (i=1; i<=x.size; i++) { printf("%d def",x.key[i]); } if(l==0)printf("\n"); }else { for (i=1; i<=x.size; i++) { printf("%d ghi",x.key[i]); } if(l==0)printf("\n"); l++; printf(" jkl"); for (i=1; i <= x.size+1; i++) { PrintBtree(*x.node[i]); } } printf("\n"); }

みんなの回答

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.2

>xが外で定義されているので7ではないですか? 実際に試してみましょう

marchpotencial
質問者

補足

なるほど! ポインタの考え方とグローバル変数がごちゃごちゃになっていたようです。もう一度考えてみます。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

そりゃそ~だ. #include <stdio.h> int x; void foo(int t) { t = 7; } int main() { x = 3; foo(x); printf("%d\n", x); return 0; } というプログラムで何が出力されると思いますか?

marchpotencial
質問者

補足

? xが外で定義されているので7ではないですか?

関連するQ&A

  • DXライブラリでマップが作れません・・・。

    今DXライブラリとVisualC++2008を使ってゲーム(アクション)を作っているのですがマップが作れません・・・、構造体?をつかってマップの描写は成功したのですが、0のところに判定を持たせることができません・・・。どのようにすればいいのでしょうか?色々試してみてもできず困っています。 ソースの一部 #include"DxLib.h" #define MAP_SIZE 64 // マップチップ一つのドットサイズ #define MAP_WIDTH 10 // マップの幅 #define MAP_HEIGHT 8 // マップの縦長さ int MapData[ MAP_HEIGHT ][ MAP_WIDTH ] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } , } ; void HYOUZI(void); void SYOKIKA(void); struct dousa{ int power; int flag; }; struct dousa jump; struct zahyou { int x,y; int img; int flag; int muki_y; int muki_x; int x1; int x2; int x3; int x4; int y1; int y2; int y3; int y4; }; struct zahyou haikei; struct charcter { int x,y; int img; int flag; }; struct charcter ziki; struct map; //初期化 void SYOKIKA(void){ jump.flag=0; ziki.x=100; ziki.y=100; ziki.img=LoadGraph("red_player.bmp"); } //背景 void HYOUZI(void){ int i,j; for( i = 0 ; i < MAP_HEIGHT ; i ++ ) { for( j = 0 ; j < MAP_WIDTH ; j ++ ) { if( MapData[ i ][ j ] == 0 ) { DrawBox( j * MAP_SIZE , i * MAP_SIZE , j * MAP_SIZE + MAP_SIZE , i * MAP_SIZE + MAP_SIZE , GetColor( 255 , 0 , 0 ) , TRUE ) ; } } } DrawGraph(ziki.x,ziki.y,ziki.img,TRUE); ScreenFlip(); } //動き void ugoki(void){ int OldX , OldY ; OldX = ziki.x ; OldY = ziki.y ; if (CheckHitKey(KEY_INPUT_RIGHT) == 1){ ziki.x=ziki.x+4; } if (CheckHitKey(KEY_INPUT_RIGHT) == 1) if (CheckHitKey(KEY_INPUT_Z) == 1) { ziki.x=ziki.x+8; } if (CheckHitKey(KEY_INPUT_LEFT) == 1){ ziki.x=ziki.x-4; } if (CheckHitKey(KEY_INPUT_LEFT) == 1) if (CheckHitKey(KEY_INPUT_Z) == 1) { ziki.x=ziki.x-8; } if(ziki.x>640){ ziki.x=-10; } if(ziki.x<-10){ ziki.x=640; } //ジャンプ jump.power-=1; ziki.y -=jump.power; if(ziki.y>400){ jump.power=0; ziki.y=400; jump.flag=0; } if (CheckHitKey(KEY_INPUT_DOWN) == 1 && jump.flag == 0){ jump.power=30; jump.flag=1; } if (CheckHitKey(KEY_INPUT_UP) == 1 && jump.flag == 0){ jump.power=20; jump.flag=1; } if( MapData[ ziki.x ][ ziki.y ] == 0 ) { ziki.x = OldX ; ziki.y = OldY ; } } int WINAPI WinMain ( HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { ChangeWindowMode(TRUE); if(DxLib_Init()==-1) { return -1; } SYOKIKA(); SetDrawScreen(DX_SCREEN_BACK); while(ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0){ HYOUZI(); ugoki(); ClearDrawScreen(); } DxLib_End(); return(0); } 分かる人がいたらぜひ教えてください(o_ _)o

  • c言語

    c言語で写真の課題を出されたのですが自分のプログラムでは上手くいきません。どこが間違っているのか教えて欲しいです。 自分のプログラム #include<stdio.h> #include<math.h> int main(){ int i,j; double c,d,x,y,z; for(i=0;i<=360;i++){ c=10*cos(i*M_PI/180); d=10*sin(i*M_PI/180); if(c>=0 && d>=0){ for(j=0;j<=1000;j++){ x=0.001*j; y =x*d/c; z=1-x*x-(sqrt(x)+y)*(sqrt(x)+y); if(z<=0.0){break;} } } if(c<=0 && d>=0){ for(j=0;j<=1000;j++){ x=-0.001*j; y=x*d/c; z=1-x*x-(sqrt(-x)+y)*(sqrt(-x)+y); if(z<=0.0){break;} } } if(c<=0 && d<=0){ for(j=0;j<=1000;j++){ x=-0.001*j; y=x*d/c; z=1-x*x-(sqrt(-x)+y)*(sqrt(-x)+y); if(z<=0.0){break;} } } if(c>=0 && d<=0){ for(j=0;j<=1000;j++){ x=0.001*j; y=x*d/c; z=1-x*x-(sqrt(x)+y)*(sqrt(x)+y); if(z<=0.0){break;} } } printf("x=%lf y=%lf z=%lf\n",x,y,z); } return(0); }

  • C言語の演算について

    次のプログラムを実行したらどう出力されますか。 微妙な代入演算の違いが分からないので、教えていただけないでしょうか。 #include<stdio.h> void main (void) { int x = 5; int y = 8; int z = 3; int a,b,c,d,e,f; a = y == x + z; b = !x; c = x + y / z; d = x *=z - 1; e = --y / --z; f = y+++ % x++; printf("%d,%d,%d,%d,%d,%d\n",a,b,c,d,e,f); } できれば途中のトレースも書いていただけると助かります。 よろしくお願いします。

  • C言語に関して

    C言語に関して 100までの自然数を文字列に変換したいのですが、以下のプログラムを実行すると、001,002,…010,…099,100のようになってしまいます。左詰めにしたいのですが、どこが間違っているかご教示下さい。 #include <stdio.h> #define N1 100 #define N2 5 int get_ketasuu(); void henkankun(); int main(void) { int i, dig, x; int num1 = N1; int num2 = N2; int buff1[N1], buff2[N1]; char buff3[N1][N2]; for (i = 0; i < N1; i++) { x = buff2[i] = buff1[i] = i + 1; dig = get_ketasuu(x); henkankun(&buff2[i], &buff3[i], dig); printf("%s\n", buff3[i]); } return 0; } int get_ketasuu(x) int x; { int dig; dig = 0; do { x /= 10; dig++; } while (x > 0); return dig; } void henkankun(x, y, dig) int *x; int dig; char (*y)[N2]; { int j, k; switch (dig) { case 1 : k = 1; case 2 : k = 10; case 3 : k = 100; } j = 0; do { (*y)[j] = (*x / k) + '0'; *x %= k; k /= 10; j++; } while (k > 0); (*y)[j] = '\0'; }

  • c言語についてです。

    文字の順番を逆さまにするプログラムなのですが実行してenterキーを押しても何もおこりません。原因がわかる方がいたら教えてほしいです。 初歩的な質問ですみません。 使っているパソコンはMacBookProです。 #include<stdio.h> void reverse(char[],char[]); void divide(char[],char[]); int main(void) { char s[100],t[100]; gets(s); reverse(s,t); divide(t,s); printf("%s %s\n",s,t); return 0; } void reverse(char s[],char t[]) { int i=0,j=0; while(s[i]!=0){ i++; } i--; while(i>=0){ t[j]=s[i]; i--; j++; } t[j]=0; return ; } void divide(char t[],char s[]){ int i=0,j=0; while(t[j]!=' '){ i++; } t[i]=0; i++; while(t[i]!=0){ s[j]=t[i]; j++; i++; } s[j]=0; return ; }

  • c言語の難しい問題について

    (c言語の問題) 下記のプログラムを完成させ、キーボードから文字列を読み込み、-1文字ずらすことによって暗号化を行うプログラムを作りなさい。ただし、ピリオド、空白などはそのままにするようにすること。 例)this is a pen. sghr hr @ qdm. #include<stdio.h> #define CHAR_NUM 256 void angou( I ) { II } int main(void) { unsigned char text[CHAR_NUM]; char moji; int i; puts("暗号化する文字を入力しなさい。"); while((moji=getchar()) !=EOF){ text[i]=moji; i++; } angou(text i); printf("%s",text); return(0); } I、IIに入る文を書きなさい。 私はIには「char x[],int y」 IIには 「if('A'<x[i]<'Z' && 'a'<x[i]<'z') int j; for(j=0;j<y;j++) x[j]=x[j]-1 else」 といれたのですが、出力がうまくでません。どうすればいいのですか?

  • C言語。どうしてコンパイルできません^^;

    最近プログラミングの勉強をはじめました。 C言語を勉強しています。 /*入力した値の、平均値・最大値・最小値・を出す。*/ #include <stdio.h> int main(void) { int x[5],i,j,w,x,y,z,sum; printf("5つの実数の平均、最大値、最小値を求めます\n"); sum = 0; for(i=0; i<5; i++){ printf("値%d:",i+1); scanf("%d",&x[i]); sum += x[i]; } for(y=0; y<5; y++){ for(j=0; j<4; j++){ w=j+1; if(x[j] < x[w]){ z = x[i]; x[i] = x[w]; x[w] = z; } } } printf("平均値:%f\n最大値:%d\n最小値:%d\n", (double)sum/5, x[0], x[4]); return 0; } Microsoft Visual C++ 2008 Express Edition でコンパイルをしようとしたのですが、 「error C2040: 'x' : 'int' は 'int [5]' と間接操作のレベルが異なります。」 と出てできませんでした^^; 何度も見直したのですが、どうしても間違っている場所がわかりません^^; どこがいけないのでしょうか^^;

  • C言語についてなのですが・・・

    さきほども上げたのですがカテゴリが間違っていたのでもう一回書き込みました まだプログラムの勉強をはじめた初心者なのですが、 テキストファイルから文字を読みこみ、大文字ならば小文字に変換し辞書順に並びかえるプログラムを作っているのですがどうしてもうまくいきません。 例えばtest.txtに XXX YYY YY XX BBB aaa aa BB とあれば aa aaa bb bbb xx xxx yy yyy と表示されるよにしたいんです。 自分が作ったプログラむはこれです。 まだテキストファイルからでなくキーボードからの入力になっていますが・・・ #include<stdio.h> #include<stdlib.h> #include<string.h> #include <ctype.h> int soto( const void *x, const void *y); int main(int argc, char *argv[]){ FILE *input; char str1[1000]; int i, j; for (i = 1; i < argc; i++){ qsort(argv[i], 1000, sizeof( char *), soto); strcpy(str1, argv[i]); for(j = 0; j < 100; j++){ str1[j] = tolower( str1[j] ); } printf("%s\n", str1); } return 0; } int soto( const void *a, const void *b){ char *x, *y; x = (char*)a; y = (char*)b; return x-y; } これだと小文字にはなるんですがソートされずに表示されてしまいます・・・ どのようにすればいけるのかご指摘のほどおねがいします

  • C言語で、引数が構造体の場合

    生徒の名前、点数、順位を表示するプログラムをつくりたいのですが、(下のような関数を用いることを前提として) void rank1(struct data *x,int n) { int i,j; for(i=0;i<n;i++) x[i].rank=1; for(i=0;i<n;i++) for(j=0;j<n;j++) if(x[i].score<x[j].score) x[i].rank++; } このような場合、関数の引数として、構造体が用いられているわけですよね? 引数が構造体の場合、どのように引数の部分を書けばいいのか分かりません。 私が考えたプログラムは下記の通りです。 もちろんうまくいきませんでした。 たぶん最後のprintfの所のrank1の引数が間違っているだけだと思うんですが、どうでしょうか? include<stdio.h> struct data { char name; int score; int rank; }; void rank1(struct data *x,int n) { int i,j; for(i=0;i<n;i++) x[i].rank=1; for(i=0;i<n;i++) for(j=0;j<n;j++) if(x[i].score<x[j].score) x[i].rank++; } void main(void) { int m; static struct data x[] = {{'A',56,1}, {'B',79,1}, {'C',34,1}, {'D',91,1}, {'E',69,1}}; for(m=0;m<5;m++) printf("%c君 %d点 %d位\n",x[m].name,x[m].score,rank1(x,m)); }

  • C言語の課題をやっております。

    C言語の課題をやっております。 ずいぶん考えたのですが、行き詰まってしまいました。 課題は、 1.構造体を作り、名簿風の決められたデータを入れる(初期化?) 2.名前の順に並べ替える 3.画面に表示する という3段階です。 これらを1つのmain関数内で作ることはできたのですが、 それぞれinput sort output関数で作り、main関数で呼び出して完成させる必要があります。 sort outputはかろうじてできたのですが、inputが動かせません。 今の考えとしては、mainでinputを呼び出し、 input関数内で構造体を初期化して、戻り値で構造体のアドレス?をmainに返して、 そのアドレスをそれぞれsort outputに渡し、処理してもらいたいと考えています。 エラーのでる箇所は、main関数の構造体アドレスのやりとりと、 input関数の戻り値のあたりで 問題のあるポインタ、とか移植性のないポインタ、などと 出てしまいます。 書いたプログラムをmain,input,sortまで載せます。 整理できておらずわかりにくいプログラムですが、考え方、間違っているところ、修正点など ご意見を頂きたく思っています。 よろしくお願いします。 # include <stdio.h> struct day { int yy; int mm; int dd; }; typedef struct hito { int NO; char NAME[10]; struct day ENTRANCE; struct day BIRTH; }HITO; void main(void){ int input(void); int output(struct hito *pt); int sort(struct hito *pt); int i,j; int x; struct hito *pt; pt=input(); sort(pt); output(pt); return; } int input(void){ int i,x; struct hito *ptt; HITO list[9]= { {1456, "okayama", 2004,4,1, 1980,2,4}, {2452, "wada", 2005,4,1, 1984,10,2}, {2552, "ikeyama", 2005,4,1, 1987,5,10}, {3456, "meguro", 2006,4,1, 1982,5,2}, {4242, "sagami", 2007,10,1, 1972,3,3}, {5123, "ohsawa", 2008,10,1, 1965,2,2}, {5222, "akagi", 2009,1,4, 1988,3,4}, {6212, "hasebe", 2009,4,1, 1990,8,3}, }; return list; } int sort(struct hito *pt){ int i,j,x; for (i=0; i<8; i++){ for(j=i+1; j<9; j++){ if((pt+i)->NAME[0] > (pt+j)->NAME[0]){ *(pt+9)=*(pt+i); *(pt+i)=*(pt+j); *(pt+j)=*(pt+9); } } } return 0; }

専門家に質問してみよう