• ベストアンサー

リストに整数値があるか判定するプログラム

↓のプログラムのint ExistTest(struct BTREE *ptr, int searchdata)を、2分木の生成後に入力した整数値がリストの中にあるかどうかを判定するプログラムにしたいのですが、うまくいきません(>_<) 入力された整数値があれば1、なければ0を返したいのですが。。 どなたかお願いしますm(__)m #include <stdio.h> #include <stdlib.h> struct BTREE {int data; struct BTREE *left; struct BTREE *right;}; void AddLeaf(struct BTREE **ptr, int newdata); void TraverseTree (struct BTREE *ptr); int ExistTest(struct BTREE *ptr, int searchdata); int ExistTest(struct BTREE *ptr, int searchdata){ if (ptr->data == searchdata){ return 1; } else{ ExistTest(ptr->right, searchdata); } } void AddLeaf(struct BTREE **ptr, int newdata){ if (*ptr == NULL){ *ptr = (struct BTREE *)malloc(sizeof(struct BTREE)); (*ptr)->data = newdata; (*ptr)->left = NULL; (*ptr)->right = NULL; } else if (newdata < (*ptr)->data){ AddLeaf(&(*ptr)->left, newdata); } else{ AddLeaf(&(*ptr)->right, newdata); } } void TraverseTree(struct BTREE *ptr){ if (ptr == NULL){ return; } else{ TraverseTree(ptr->left); printf("%3d", ptr->data); TraverseTree(ptr->right); } } int main(void){ struct BTREE *root = NULL; int newdata; int searchdata; while(1){ printf("data > "); scanf("%d", &newdata); if (newdata < 0)break; AddLeaf(&root, newdata); TraverseTree(root); putchar('\n'); } /*ExistTest*/ /* printf("num? : "); scanf("%d", &searchdata); ExistTest(root ,searchdata); */ return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

●『ExistTest』関数の考え方 ・『ExistTest』関数は『AddLeaf』関数に整数値を判定する部分を追加しれば  簡単に出来ます。既に『AddLeaf』関数は正しく出来ているので、この関数の  『malloc』部分を『return(0);』として、整数値を判定する部分を挿入すればよい。 ・下にサンプルと追加・変更部分を示します。 ●サンプル int ExistTest( struct BTREE *ptr, int searchdata ) {  if ( ptr == NULL ){   return( 0 ); ←ここが重要(変更部分)  }  else if ( searchdata == ptr->data ){ ←整数値の判定(追加部分)   return( 1 ); ←一致したら 1 を返す  }  else if ( searchdata < ptr->data ){   return( ExistTest(ptr->left,searchdata) ); ←『AddLeaf』関数の Left とほぼ同じ  }  else{   return( ExistTest(ptr->right,searchdata) ); ←『AddLeaf』関数の right とほぼ同じ  } } ●『AddLeaf』関数をもっと分かりやすく記述 int AddLeaf( struct BTREE **ptr, int newdata ) {  struct BTREE *p = *ptr;    if ( p == NULL ){   if ( (p = (struct BTREE *)malloc(sizeof(struct BTREE))) == NULL ){    return( 0 ); ←メモリ不足   }   p->data = newdata;   p->left = NULL;   p->right = NULL;   *ptr = p;   return( 1 ); ←確保!  }  else if ( newdata < p->data ){   return( AddLeaf(&p->left,newdata) );  }  else{   return( AddLeaf(&p->right,newdata) );  } } 最後に: ・『AddLeaf』関数の戻り値は、正常ならば 1 を、メモリ不足ならば 0 を返す。 ・以上。おわり。

その他の回答 (1)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

「うまくいかない」じゃなくて、もう少し具体的に書きましょう。 で、みたところExistTestが未完成なのが問題みたいなのだけど わからなくて書いていない? それともポカミス? int ExistTest(struct BTREE *ptr, int searchdata) { if (!ptr) return 0; if (ptr->data == searchdata){ return 1; } else if (ptr->data > searchdata) { return ExistTest(ptr->left, searchdata); } else{ return ExistTest(ptr->right, searchdata); } } こんな感じにすればとりあえずは動くと思います。 あとお小言(笑) 木を構成する要素のための構造体に TREE はないのではないでしょうか。 それはおいても、二進木(Binary Tree)以外に B木(B-Tree)ってのがありますので、その意味からも BTREEって名前はあまりよくないでしょう。

関連するQ&A

  • プログラムについて

    2分木のプログラムなのですが、関数部分を作るという学校の問題なのですが、習いはじめで構造体など殆ど分かりません。ヒントでも良いので教えてください。合っていないとは思いますが、一応初期化の部分と、終了の部分、ノードの追加部分は考えました。 typedef struct t_Btree { struct t_Btree *left; struct t_Btree *right; int data; } Btree; // Btreeの初期化 void Btree_ini(Btree *a, int b) { a->left=NULL; a->right=NULL; a->data=b; a = (Btree *)malloc(sizeof(Btree)); } // 領域の開放 void Btree_end(Btree *a, int b) { free(a); } // 新しいノードを追加 void Btree_ad(Btree *a, int b) { Btree_tansaku(a, b); a = (Btree *)malloc(sizeof(Btree)); self->left_ = NULL; self->right_ = NULL; self->data_ = b; } // 探索し、bに一致するデータのポインタを返す void *Btree_tansaku(const Btree *a, int b) { } // aのデータのみを出力 void Btree_pri(const Btree *a) { } // 全体を出力 void Btree_tpri(const Btree *a) { } int main(void) { int i; int d[] = {7,3,6,4,1,9,2,0,10,8}; Btree bt; Btree_ini(&bt,5); for(i=0;i<10;i++) Btree_ad(&bt,x[i]); Btree_tpri(&bt); Btree_end(&b); return 0; } おねがいします。

  • 二分探索木のプログラム

    2分探索木のプログラムを作っているのですが、実行するとセグメテーション違反がでます。何が間違っているんでしょうか? #include<stdlib.h> struct node{ struct node *left,*right; int datum; }; struct bintree{ struct node *root; }; /*空木を作成*/ void InitTree(struct bintree *p) { p->root=NULL; } /*木全体を削除*/ void ClearTree(struct bintree *p) { struct bintree *q,*r; if(p->root!=NULL){ q->root=p->root->left; ClearTree(q); r->root=p->root->right; ClearTree(r); free(p->root); } } /*第二引数で指定された値が木の節点のラベルに存在すれば、その節点へのポインタを返す。なければ、NULLを返す。*/ struct node * SearchNode(struct bintree *p,int x) { struct bintree *q,*r; struct node *a=p->root; int cond=x-(a->datum); if(a==NULL) return NULL; else if(cond==0) return a; else if(cond<0){ q->root=p->root->left; SearchNode(q,x); } else{ r->root=p->root->right; SearchNode(r,x); } } /*第二引数で指定された値が木の節点のラベルに存在すれば、NULLを返す。なければ、追加して、新たに作成された節点へのポインタを返す。*/ struct node * InsertNode(struct bintree *p,int x) { struct bintree *q,*r; struct node *a=p->root; int cond=x-(a->datum); if(a==NULL){ a=(struct node *)malloc(sizeof(struct node)); a->datum=x; a->left=a->right=NULL; return a; } else if(cond==0) return NULL; else if(cond<0){ q->root=p->root->left; a->left=InsertNode(q,x); } else{ r->root=p->root->right; a->right=InsertNode(r,x); } } int main() { struct bintree *p; struct node *a; InitTree(p); a=InsertNode(p,5); InsertNode(p,3); InsertNode(p,0); InsertNode(p,10); SearchNode(p,5); ClearTree(p); return 0; }

  • 今、構造体の勉強をしているのですが…

    初心者です。 今、木構造を生成するプログラムを勉強しております。 参考書のプログラムの中に 新たなノードを生成する関数。 void AddLeaf(struct BTREE **ptr,int newdata) とあるのですが、 struct BTREE **ptr って何ですか?? 特に*が二つあるところがわからないです。 *(*ptr)となっているから ptrのアドレスの指す実体?? って事なのでしょうか?? 少々混乱気味です(^^;) どなたか助言お願いします

  • list構造。。。

    リストの末尾にデータを追加すると、最後に追加したデータで今までのリストのデータが上書きされてしまいます。。 以下に、ソースを掲載させていただきます。 void SetNode(List* node_first, List* node_second, int *data) { node_first->move = data; node_first->next = node_second; return ; } /*末尾に挿入*/ void Insert_Tail(List **head, int* data) { List *ptr = *head; if(ptr == NULL){ *head = (List*)calloc(1,sizeof(List)); SetNode(*head, NULL, data); return ; }else{ while(ptr->next != NULL){ ptr = ptr->next; } ptr->next = (List*)calloc(1,sizeof(List)); SetNode(ptr->next, NULL, data); } return ; } void show_list(List *list) { List *ptr = list; while(ptr != NULL){ printf("%d\n",*(ptr->move)); ptr = ptr->next; } return ; } int main(int argc, char** argv) { /*宣言*/ Node* root; /**/ List* top; /* 手順のリスト */ int judge; top = NULL; do{ printf("num:"); scanf("%d",&judge); switch(judge){ case 1: /*データを末尾に追加*/ printf("mem:"); scanf("%d",mem); root->board = mem; Insert_Tail(&top, root->board); break; case 2: /*リストを頭から表示*/ show_list(top); break; default: break; } }while(judge != 0); return 0; } 自分は最後のリストまでたどって、callocしたつもりなのですが、どうもそうではないようで、困っています。 どうか、御指導の程、お願いします。

  • リストがわかりません。

    下のプログラムはリストに昇順になるように 入力された要素を挿入するプログラムですが、うまくいきません。どうか教えてください。 #include<stdio.h> static int count; struct node_tag{ int data; struct node_tag *next; }; typedef struct node_tag node_t; node_t *insert_node( node_t *t, int d ); node_t *print_list( node_t *r ); int main( void ) { node_t root; int data; root.next = NULL; for ( ;; ) { printf( "> " ); if ( scanf( "%d", &data ) != 1 ) break; insert_node( &root, data ); print_list( &root ); } return; } node_t *insert_node( node_t *t, int d ) { node_t *new_node; new_node = (node_t *)malloc( sizeof(node_t) ); if( new_node == NULL ) return NULL; if(count == 0) { new_node -> data = d; new_node -> next = NULL; t -> next = new_node; count++; } else { for(; t -> next != NULL; t = t -> next) { if(t -> next -> data >= d) break; } if(t -> next -> data == d) return; else if(t -> next -> data > d) { new_node -> data = d; new_node -> next = t -> next; t -> next = new_node; } else if(t -> next == NULL) { new_node -> data = d; t -> next = new_node; new_node -> next = NULL; } } return new_node; } node_t *print_list( node_t *r ) { node_t *p; printf("[ "); for( p = r -> next; p != NULL; p = p -> next) { printf("%d ", p -> data); } printf("]\n"); }

  • (構造体)双方向連結リストの作成!

    ダミーノードを先頭に、双方向連結リストを作成したいのですがなかなかうまくできません。とりあえず、ダミーノード無しのものはなんとか出来ましたが、循環連結がうまくいっていない次第です。 どうかお力添え願います。 #include<stdio.h> #include<malloc.h> #include<process.h> typedef struct node{ struct node *left; char name[20]; int age; struct node *right; }NODE; NODE *memalloc(void); void main(void) { NODE *head, *tail, *p; tail = NULL; while(p = memalloc(), printf("名前 年齢入力(Ctrl + Zで終了)>"), scanf("%s %d", p -> name, &p -> age) != EOF){ p -> left = tail; tail = p; } p = tail; head = NULL; while(p != NULL){ p -> right = head; head = p; p = p -> left; } head -> left = tail; p = head; printf("リスト表示\n"); while(p != NULL){ printf("名前:%20s 年齢:%5d\n", p -> name, p -> age); p = p -> right; } } NODE *memalloc(void) { NODE *ptr; if((ptr = (NODE *)malloc(sizeof(NODE))) != NULL){ return ptr; } printf("\n動的メモリ割当に失敗しました。\n"); exit(1); return 0; }

  • C言語 二分木探索

    今、int型の二分木にデータを追加する関数(引数は二分木へのポインタと追加する値、追加されたノードへのポインタを返す)をつくろうとしてます。 以前リストにデータを追加する関数をつくったのでそれを変更してつくろうとしているのですが途中までいってつまってしまいました。 つくりかたを教えてください。 よろしくお願いします! struct BinaryTreeNode{ int data; struct BinaryTreeNode *l_next; struct BinaryTreeNode *r_next; }; struct BinaryTree{ int node_num; struct BinaryTreeNode *root; }; BinaryTreeNode *BinaryTreeNodeAlloc(void) { BinaryTreeNode *node; node = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode)); if (node == NULL) { return (NULL); } node->l_next = NULL; node->r_next = NULL; return (node); } BinaryTreeNode *BinaryTreeDataAdd(BinaryTree *list, int x) { BinaryTreeNode *ptr; BinaryTreeNode *prev; BinaryTreeNode *new_node; ptr = list->root; prev = NULL; while (ptr) {       ←?? if (ptr->data < x) { prev = ptr; ptr = ptr->next; } else if (ptr->data == x) { return (NULL); } else { new_node = BinaryTreeNodeAlloc(); if (new_node == NULL) { exit (0);                ←?? } new_node->data = x; new_node->next = ptr; if (prev != NULL) { prev->next = new_node; } else { list->head = new_node; } list->node_num++; return (new_node); } } new_node = BinaryTreeNodeAlloc(); if (new_node == NULL) { exit (0); } new_node->data = x; new_node->r_next = NULL; new_node->l_next = NULL; if (prev != NULL) { prev->next = new_node; } else { list->head = new_node; } list->node_num++; return (new_node); }

  • 二分法のプログラム

    関数x^3-7x^2-6x+2を二分法で解くプログラムを作ったのですが、エラーが出てコンパイルできません。訂正箇所を教えて下さい。 宜しくお願い致します。 #include<stdio.h> #include<math.h> #define EPSILON 0.1E-5 #define TURE 1 #define FALSE 0 int kansu(int x); void Nibunho(left,right,sol,flag); double left,right; int flag; int main(void) { printf("区間の左端と右端は?\n"); scanf("%lf %lf",&left,&right); flag=FALSE; Nibunho(left,right,&root,&flag); if(flag) printf("解 = %e (繰り返し回数 = %d)\n",root,k); else { printf("入力した範囲で解は求まりませんでした。\n"); printf("f(%e) = %e \n",root,k); } return 0; } int kansu(int x) { int f(double x) f(x)=x*x*x-7.0*x*x-6.0*x+2.0; return(f(x)); } void Nibunho(left,right,sol,flag) { double left,right,*sol; int *flag; double a,b,c,fa,fb,fc; k=0; a=left; b=right; do { k++; c=(a+b)/2.0; fc=f(c); fa=f(a); fb=f(b); if(fabs(fc)<1.0e-10) { a=c; b=c; *flag=TRUE; } else { if( (fa * fc < 0.0) || (fb * fc < 0.0) ) { *flag = TRUE; if( (fa*fc) < 0.0 ) b=c; else a=c; } else { if( fabs(fa) > fabs(fb) ) a=c; else b=c; } } } while((b-a)>EPSILON) *sol=(a+b)/2.0; }

  • C言語に関する質問

    初めて質問させて頂きます。C言語初心者です。 実は講義で「ファイル中の英文を単語に分けてその出現頻度をカウントするコードを木構造を用いて出力せよ」という課題が出ました。 そこで、参考にするコードを検索しましたところ、以下のURLにあるベストアンサーのコードが近いと感じました。 http://okwave.jp/qa/q4155655.html コードの内容は以下の通りになります。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> typedef struct node Node; struct node{ char *word; int count; Node *left,*right; }; Node *root=NULL; void compose(FILE *fp); void inorder(Node *p); void strlower(char *s); int main(int argc, char *argv[]) { FILE *fp; Node *new; fp=fopen(argv[1],"r"); if(fp==NULL){puts("ファイルを開けません");return(-1);} compose(fp); inorder(root); return (0); } void strlower(char *s){ while(*s!=NULL){*s=tolower(*s);s++;} } void compose(FILE*fp){ Node **p,*new; char buf[256]; while(1){ fscanf(fp,"%[^a-zA-Z0-9]",buf); if(fscanf(fp,"%[a-zA-Z0-9]",buf)==EOF)break; strlower(buf); if(root==NULL){ new=(Node *)malloc(sizeof(Node)); new->left=NULL; new->right=NULL; new->word=strdup(buf); new->count=1; root=new; }else{ *p=root; while(1){ if(strcmp(buf,(*p)->word)==0){ (*p)->count++;break; }else if(strcmp(buf,(*p)->word)<0){ if((*p)->left==NULL){ new=(Node *)malloc(sizeof(Node)); new->left=NULL;new->right=NULL;new->word=strdup(buf);new->count=1; (*p)->left=new; break; }else{ *p=(*p)->left; } }else{ if((*p)->right==NULL){ new=(Node *)malloc(sizeof(Node)); new->left=NULL; new->right=NULL; new->word=strdup(buf); new->count=1; (*p)->right=new; break; }else{ *p=(*p)->right; } } } } } } void inorder(Node*p){ if (p==NULL) return; inorder(p->left); printf("%s %d\n",p->word, p->count); inorder(p->right); } しかし、これをそのままコンパイル・実行すると、コンパイル時に以下の注意が出ます。 warning comparison between pointer and integer ('int' and 'char *') while(*s!=NULL){*s=tolower(*s);s++;} 上記の注意を無視してそのまま実行すると、segmatation faultが出てしまいますorz おそらく、sの型が*s=s[]なので、注意の中の「s++」の部分で誤作動を起こしている(s++を実行するにはsはint型でなければならない)と思うのですが、どうコード文を変えれば良いのかがよくわかりません。 どなたかお教え頂けると幸いです。どうぞよろしくお願いしますm(_ _)m

  • List構造

    Listの尻にノードを追加する関数で困っています。 以下に、ソースの一部を掲載させていただきます。 typedef struct __node{ int data; struct __node *next; }Node; ... /*リストの尻にノードを追加する関数 * 引数: head. リストの先頭ノードのポインタ data. リストの尻に追加したいint型の変数*/ void Insert_Tail(Node *head, int data) { Node *ptr = head; if(ptr == NULL){ /*<ノードが存在しない時には追加されない>*/ /*領域の確保*/      head = (Node*)calloc(1,sizeof(Node)); /*データをセット*/ head->data = data; head->next = NULL; return ; }else{ /*<ノードが存在するときには正常に動作>*/ while(ptr->next != NULL){ ptr = ptr->next; } /*領域の確保*/ ptr->next = (Node*)calloc(1,sizeof(Node));      /*データのセット*/ ptr->next->data = data; ptr->next->next = NULL; } } コメントアウトにも書かせていただきましたが、ノードがすでに存在するときには、正常にノードの最後に追加してくれるのですが、ノードが存在しない時にはリストに追加してくれません。 どうかご指導、ご指摘の程お願いします。

専門家に質問してみよう