C言語で2分探索木を2分木に変える方法

このQ&Aのポイント
  • C言語で2分探索木を2分木に変える方法について教えてください。
  • 2分木のプログラムを書いている際に、指定の数列を2分木に変換したいです。
  • 現在取り組んでいるプログラムの一部を引用し、問題の詳細を説明してください。
回答を見る
  • ベストアンサー

c言語で2分探索木のを2分木に変えたい

2分木のプログラムを書いているのですが、ある数列を2分木にしたいのです。 2分探索木のプログラムを参考に書いていて、その一部が typedef int BSTREE_K_TYPE; typedef int BSTREE_V_TYPE; struct bsnode { BSTREE_K_TYPE key; BSTREE_V_TYPE value; struct bsnode *left; struct bsnode *right; }; typedef struct bsnode BSTREE_NODE; int gShortFormat = 1; void error(char *msg){ fflush(stdout); fprintf(stderr, "%s\n", msg); exit(1); } BSTREE_NODE *createNode(BSTREE_K_TYPE x){ BSTREE_NODE *new; new = malloc(sizeof(BSTREE_NODE)); if(new == NULL) error("createNode: メモがありません"); new->key = x; new->value = 0; new->left = NULL; new->right = NULL; return new; } BSTREE_NODE *insertNode(BSTREE_NODE *p, BSTREE_K_TYPE x){ if (p == NULL){ } else if (p->key == x){ error("insertNode: 指定キーのノードが含まれています"); } else if (p->key > x){ p->left = insertNode(p->left, x); } else { p->right = insertNode(p->right, x); } return p; } BSTREE_NODE *inputBSTree(BSTREE_NODE *btree, char *str[], int len, int *end){ BSTREE_K_TYPE x; int i, n = 0; for(i = 0; i < len; i++){ if(!strcmp(str[i], "--")) break; x = atoi(str[i]); if(btree == NULL) btree = createNode(x); else btree = insertNode(btree, x); n++; } *end = n; return btree; } このinsertNodeのifの条件を変えればいいのかと思い、いろいろ試してみたのですが、 左部分木には左側にしか葉がなく、右部分木には右にしか葉がないようなものしかできませんでした もう何時間も悩んだのですが自分の知識では手づまりです どうかよろしくお願いします。

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

  • ベストアンサー
  • hrsmmhr
  • ベストアンサー率36% (173/477)
回答No.7

ゴミは解りません 木は、入力が昇順ならそうなって正解です。 つまり入力によらない一意の結果はでません 一意の結果にするには 例えば、上位ビットから0/1で分けるとかすればできるでしょう ただ枝と葉を分けないといけないでしょう

kagari321
質問者

お礼

そうですか… ありがとうございました!

その他の回答 (7)

  • hrsmmhr
  • ベストアンサー率36% (173/477)
回答No.8

ゴミの件ですが、 携帯で見ていたので気が付きませんでしたが btreeをcreateNodeするときに使うxが初期化されていないですのでゴミが入ります xを初期化するか、btree->keyは意味がないので表示しないようにするかだと思います

kagari321
質問者

お礼

ありがとうございます ゴミはうまく消すことができました

  • hrsmmhr
  • ベストアンサー率36% (173/477)
回答No.6

どこのどういうエラーでしょうか? *->p->keyは見たことがないです そこなら &((*p)->left) ではダメですか?

kagari321
質問者

お礼

そのように変えたところコンパイルはうまくいきました。 しかし実行すると a.exe 1 2 3 5 6 7 入力データ [ 4235448 [ 1 _ [ 2 _ [ 3 _ [ 5 _ [ 6 _ 7 ] ] ] ] ] _ ] と最初に関係ない値が入り、さらに右側にしか葉がない木になってしまったようです。

  • hrsmmhr
  • ベストアンサー率36% (173/477)
回答No.5

二つの関数を書き換えてみました。参考にしてみてください。 void insertNode(BSTREE_NODE **p, BSTREE_K_TYPE x){ if (*p == NULL) *p=createNode(x); else if (*p->key == x) error("insertNode: 指定キーのノードが含まれています"); else if (*p->key > x) insertNode(&(*p->left), x); else insertNode(&(*p->right), x);} } BSTREE_NODE *inputBSTree(BSTREE_NODE *btree, char *str[], int len, int *end){ BSTREE_K_TYPE x; int i; if(btree == NULL) btree = createNode(x); for(i = 0; i < len; i++){ if(!strcmp(str[i], "--")) break; x = atoi(str[i]); insertNode(&btree, x); } *end = i; return btree; }

kagari321
質問者

お礼

insertNodeでコンパイルエラーがでたので void insertNode(BSTREE_NODE **p, BSTREE_K_TYPE x){ if (*p == NULL) {*p=createNode(x); }else if (*->p->key == x) {error("insertNode: 指定キーのノードが含まれています"); }else if (*->p->key > x) {insertNode(&(*->p->left), x); }else {insertNode(&(*->p->right), x); } } と書き換えたのですが、まだエラーが出てしまいます…

  • hrsmmhr
  • ベストアンサー率36% (173/477)
回答No.4

No3さんの回答で気が点きましたが 私の *p=x; を *p=createNode(x); ではダメでしょうか? その場合だとbtreeはループで毎回createNodeするべきではないです

kagari321
質問者

お礼

コンパイルがうまくできませんでした 一応2分探索木のプログラムとしては下のような形です。 これだと2分探索木なので、ただの2分木を作りたいのです。 例えば 1 2 3 4 5 6 のとき     1    / \   2     3  / \  / 4    5 6 としたいです。 #include <stdio.h> #include <stdlib.h> typedef int BSTREE_K_TYPE; typedef int BSTREE_V_TYPE; struct bsnode { BSTREE_K_TYPE key; BSTREE_V_TYPE value; struct bsnode *left; struct bsnode *right; }; typedef struct bsnode BSTREE_NODE; void error(char *msg); void destroyBSTree(BSTREE_NODE *p); BSTREE_NODE *insertNode(BSTREE_NODE *p,BSTREE_K_TYPE x); int isLeafNode(BSTREE_NODE *p); void printBSTree(BSTREE_NODE *p, int tabs, int brief); BSTREE_NODE *inputBSTree(BSTREE_NODE *btree, char *str[], int len, int *end); int main(int argc, char *argv[]){ BSTREE_NODE *bstree = NULL; BSTREE_NODE *result; BSTREE_K_TYPE x; int n1; bstree = inputBSTree(bstree, &argv[1], argc -1, &n1); printf("入力データ "); printBSTree(bstree, 0, 1); destroyBSTree(bstree); return 0; } int gShortFormat = 1; void error(char *msg){ fflush(stdout); fprintf(stderr, "%s\n", msg); exit(1); } BSTREE_NODE *createNode(BSTREE_K_TYPE x){ BSTREE_NODE *new; new = malloc(sizeof(BSTREE_NODE)); if(new == NULL) error("createNode: メモがありません"); new->key = x; new->value = 0; new->left = NULL; new->right = NULL; return new; } void destroyNode(BSTREE_NODE *del){ memset(del, 0, sizeof(BSTREE_NODE)); free(del); } void destroyBSTree(BSTREE_NODE *p){ if(p == NULL) return; destroyBSTree(p->left); destroyBSTree(p->right); destroyNode(p); } BSTREE_NODE *insertNode(BSTREE_NODE *p, BSTREE_K_TYPE x){ if (p == NULL){ p = createNode(x); } else if (p->key == x){ error("insertNode: 指定キーのノードが含まれています"); } else if (p->key > x){ p->left = insertNode(p->left, x); } else { p->right = insertNode(p->right, x); } return p; } int isLeafNode(BSTREE_NODE *p){ return(p->left == NULL) && (p->right == NULL); } void printSubBSTree(BSTREE_NODE *p){ if(p == NULL){ printf("_"); return; } if(gShortFormat !=0 && isLeafNode(p)){ printf("%d", p->key); }else{ printf("[ "); printf("%d ", p->key); printSubBSTree(p->left); printf(" "); printSubBSTree(p->right); printf(" ]"); } } void printBSTree(BSTREE_NODE *p, int tabs, int brief){ int i; gShortFormat = brief; for(i = 0; i < tabs; i++) printf("\t"); printSubBSTree(p); printf("\n"); fflush(stdout); } BSTREE_NODE *inputBSTree(BSTREE_NODE *btree, char *str[], int len, int *end){ BSTREE_K_TYPE x; int i, n = 0; for(i = 0; i < len; i++){ if(!strcmp(str[i], "--")) break; x = atoi(str[i]); if(btree == NULL) btree = createNode(x); else btree = insertNode(btree, x); n++; } *end = n; return btree; }

回答No.3

No.2の方の回答に、さらに、次の部分も、こうしないとだめじゃないかな? BSTREE_NODE *inputBSTree(BSTREE_NODE *btree, char *str[], int len, int *end){ BSTREE_K_TYPE x; int i, n = 0; for(i = 0; i < len; i++){ if(!strcmp(str[i], "--")) break; x = atoi(str[i]); if(btree == NULL) btree = createNode(x); else /*btree =*/ insertNode(btree, x); //←ここね。 n++; } *end = n; return btree; }

kagari321
質問者

お礼

回答ありがとうございます それで試してみましたが、2分木ではなくやはり2分探索木になってしまいました…

  • jjon-com
  • ベストアンサー率61% (1599/2592)
回答No.2

手元にCコンパイラがないのでざっと目視でコードを追ってみただけなのですが, insertNode 内の最初のif分岐の中身の1行が抜けていますよね。 BSTREE_NODE *insertNode(BSTREE_NODE *p, BSTREE_K_TYPE x){ if (p == NULL){ p = createNode(x); } else if (p->key == x){ error("insertNode: 指定キーのノードが含まれています"); } else if (p->key > x){ p->left = insertNode(p->left, x); } else { p->right = insertNode(p->right, x); } return p; }

kagari321
質問者

お礼

投稿するときに間違えて消してしまったようです ありがとうございます

  • hrsmmhr
  • ベストアンサー率36% (173/477)
回答No.1

プログラムよく判らないのですが rootがまず必要なこと(btreeのようですが、ループで書き換える必要がないです)、 xをpのleftかrightにリンクする箇所がない気がします InsertNodeで戻り値が必要なくて、引数にダブルポインタ**pを使って *p==NULLのときに*p=x;とすれば できるのかも…

kagari321
質問者

お礼

回答ありがとうございます でもできませんでした…

関連するQ&A

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

    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; }

  • 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); }

  • 2分木のノードの指定方法を変えたい

    下のプログラムはコマンドライン引数できまった形で入力した数を2分木にしてそれを表示させるc言語のプログラムです。 きまった形というのは 短縮形は [ 8 [ 7 2 5 ] [ 3 1 _ ] ] 短縮形でないのは [ 8 [ 7 [ 2 _ _ ] [ 5 _ _ ] ] [ 3 [ 1 _ _ ] _ ] ] ] のような形で、実行結果はそれぞれ a.exe [ 8 [ 7 2 5 ] [ 3 1 _ ] ] 入力データ [ 8 [ 7 2 5 ] [ 3 1 _ ] ] a.exe [ 8 [ 7 [ 2 _ _ ] [ 5 _ _ ] ] [ 3 [ 1 _ _ ] _ ] ] ] 入力データ [ 8 [ 7 2 5 ] [ 3 1 _ ] ] のようになります。 これをこのような形ではなくコマンドラインで 8 7 3 2 5 1 と入力するだけで2分木になるように 下のプログラムを変えたいのです。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef int BITREE_TYPE; /* 格納データの型 */ struct node { BITREE_TYPE value; /* ノードの値 */ struct node *left; /* 左ノードのアドレス */ struct node *right; /* 右ノードのアドレス */ }; typedef struct node BITREE_NODE; void error(char *msg); BITREE_NODE *createNode(BITREE_TYPE x); void destroyBITree(BITREE_NODE *p); int isLeafNode(BITREE_NODE *p); void printBITree(BITREE_NODE *p, int tabs, int brief); BITREE_NODE *inputBITree(char *str[], int len, int *end); int gShortFormat = 1; /*1ならば短縮形で出力する*/ void error(char *msg){ fflush(stdout); fprintf(stderr,"%s\n", msg); exit(1); } BITREE_NODE *createNode(BITREE_TYPE x){ BITREE_NODE *new; new = malloc(sizeof(struct node)); if(new == NULL) error("createNode: メモリがありません"); new->value = x; new->left = NULL; new->right = NULL; return new; } void destroyBITree(BITREE_NODE *p){ if(p == NULL) return; destroyBITree(p->left); destroyBITree(p->right); memset(p, 0, sizeof(struct node)); free(p); } int isLeafNode(BITREE_NODE *p){ return(p->left == NULL) && (p->right == NULL); } void printSubtree(BITREE_NODE *p){ if(p == NULL){ printf("_"); return; } if(gShortFormat != 0 && isLeafNode(p)){ printf("%d", p->value); } else{ printf("[ "); printf("%d ", p->value); printSubtree(p->left); printf(" "); printSubtree(p->right); printf(" ]"); } } void printBITree(BITREE_NODE *p, int tabs, int brief){ int i; gShortFormat = brief; for (i = 0; i<tabs; i++) printf("\t"); printSubtree(p); printf("\n");fflush(stdout); } BITREE_NODE *inputBITree(char *str[], int len, int *end){ BITREE_NODE *p; int i =0; if(len < 1) error("inputBITree:データがありません"); /*短縮形の処理*/ if(strcmp(str[0], "[") != 0){ if(strcmp(str[0], "_") == 0) error("inputBTITree:値に_は指定できません"); *end =1; return createNode(atoi(str[0])); } p = createNode(atoi(str[1])); i = 2; if(strcmp(str[i], "_") != 0){ p->left = inputBITree(&str[i], len -i, end); i+= *end; } else{ i++; } if(strcmp(str[i], "_") != 0){ p->right = inputBITree(&str[i], len -i, end); i+= *end; } else{ i++; } if(strcmp(str[i], "]") != 0) error("inputBITree: 入力データが]で終わっていません"); *end = i + 1; return p; } int main(int argc, char *argv[]){ BITREE_NODE *p; int end = 0; p = inputBITree(argv+1, argc-1, &end); printf("入力データ "); printBITree(p,0,1); destroyBITree(p); return 0; }

  • 二分探索木への挿入

    今学校で二分探索木を勉強しています。二分探索木に要素を挿入したいのですが、うまくいかないのでアドバイスをいただけないでしょうか。ファイル中の英文を単語に分けてその出現頻度をカウントするプログラムです。とりあえず二分探索木を作るところまではなんとか完成させたいです。 #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; Node *compose(FILE *fp); void inorder(Node *p); int main(int argc, char *argv[]) { FILE *fp; Node *new; fp=fopen(argv[1],"r"); if(fp==NULL){ puts("ファイルを開けません"); return(-1); } new=(Node *)malloc(sizeof(Node *)); new=compose(fp); inorder(new); return (0); } Node *compose(FILE *fp) { Node **p,*new; char buf[20]; p=&root; while(fscanf(fp,"%[-a-z-A-Z0-9_]",buf)!=EOF){ while(*p!=NULL){ (*p)->count=0;  /*countを0で初期化したいけどwhileの外にこの1行を出すとエラーが出る*/ buf[0]=tolower(buf[0]); strdup(buf); if(strcasecmp(buf,(*p)->word)==0){   /*if文にしかはいらない…*/ (*p)->count++; printf("%d\n",(*p)->count); }else if(strcasecmp(buf,(*p)->word)<0){ p=&(*p)->left; }else{ p=&(*p)->right; } } new=(Node *)malloc(sizeof(Node *)); new->left=NULL; new->right=NULL; new->word=buf; *p=new; fscanf(fp,"%*[^-a-z-A-Z0-9_]"); } return(new); } void inorder(Node *p) { if(p==NULL) return; printf("%s",p->word); if(p->count!=0){ printf("%d",p->count); } inorder(p->right); inorder(p->left); }

  • 2分探索木の高さを求めるプログラムの質問です。

    2分探索木の高さを求めるプログラムを作成しているのですが、 下に書いたプログラムだと上手くいきません・・。 int compute_height(struct BST_Node *p){ int lh=0, rh=0, Max; if(p==NULL){ return 0; } lh=compute_height(p->left); rh=compute_height(p->right); if(lh > rh){ return Max=lh; } else{ return Max=rh; } } どこがおかしいのでしょう。教えてください。 よろしくお願いします。

  • C言語 2分木探索について質問です

    C言語初心者です。 2分木構造体 struct node{ int data; Tree left_subtree; Tree right_subtree; } を上記のように定義した場合、 2分木の根節点のポインタ struct node *Tree を引数として与えられたとき、 2分木内の節点に保持された整数データの総和を戻り値として返す関数 int sum_data(Tree t);を再帰呼び出しで作成してみたのですが、正しいでしょうか? ■2分木内の節点に保持された整数データの総和を戻り値として返す関数 int sum_data(Tree t) {     // 左分木、右分木のどちらも存在しなければ根節点の値を返す     if ((t->left_subtree == NULL) && (t->right_subtree == NULL))      {      return t->data;    }     else// どちらか存在していれば再帰呼び出しする    {      return (t->data + sum_data(t->left_subtree) + sum_data(t->right_subtree))    } } ご指摘ありましたら、お願いしますm(_ _)m

  • 多分探索木の高さを測定する関数について

    今、多分探索木の高さを測定する関数を作成していますが、行き詰ってしまいました。 二分探索木の深さを求める関数を改良すればよろしいと思ったんですが。 どうもうまくいきません。助言お願いします。 以下、二分探索木の高さを求める関数を貼っときます。 int compute_height(NODE *root){ int lh=0, rh=0, Max; if(root==NULL){ return 0; } lh=compute_height(root->left)+1; rh=compute_height(root->right)+1; if(lh > rh){ return Max=lh; }else{ return Max=rh; } } 多分木探索の構造体定義は以下のようです typedef struct node{  int key[16]; //キー配列 int nkeys ; // キーの個数(実際の) struct node *refs[17] ; // 子への参照欄 } NODE

  • C言語でセグメンテーションエラー

    環境はUbuntu Feisty Fawn gcc 4.1.2 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 32 #define DEBUG struct node{ char *moji; struct node *left,*right; }; typedef struct node NODE; void error(char *msg){ fflush(stdout); fprintf(stderr, "%s\n", msg); exit(1); } NODE *createNode(char *x){ NODE *new; new = malloc(sizeof(NODE)); if(new == NULL){ error("メモリがありません。\n"); } new->moji = x; new->left = NULL; new->right = NULL; return new; } NODE *insertNode(NODE *p, char *x){ if(p == NULL){ p = createNode(x); }else if(strcmp(p->moji, x) == 0){ return NULL; }else if(strcmp(p->moji, x) > 0){ p->left = insertNode(p->left, x); }else{ p->right = insertNode(p->right, x); } return p; } void printTree(NODE *p){ if(p == NULL) return; printTree(p->left); printf("%s\n",p->moji); printTree(p->right); } int main(int argc, char *argv[]){ FILE *fp; char *buf = malloc(sizeof(char) * MAX); char *ans = malloc(sizeof(char) * MAX); NODE *p = malloc(sizeof(NODE)); if( argc > 2 ){ printf("ファイルの指定は一つだけです。\n"); return -1; }else if(argc == 1){ printf("ファイルを指定してください。\n"); return -1; } fp = fopen( argv[1] , "r" ); if( fp == NULL ){ printf("ファイル読み込みに失敗しました。\n"); return -1; } while(fscanf(fp,"%s",buf) == 1){ ans = strtok(buf," -,."); p = insertNode(p, ans); while(ans != NULL){ ans = strtok(NULL," -,."); if(ans != NULL){ p = insertNode(p, ans); } } } printTree(p); fclose(fp); return 0; } このファイルを読み込んで記憶させたいんです。 file.txt ここから下がファイルの中身 The Java programming language is a general-purpose, concurrent, class-based, object-oriented language. It is designed to be simple enough that many programmers can achieve fluency in the language. どこがいけないとおもいますか?

  • 二分木のデータ入力について

    C言語についての質問です。 キューと再起関数を使って2分木にデータを入れようとしたところ、以下のようなエラーが発生いたしました。 ddd.c: 関数 ‘dequeue’ 内: ddd.c:80:9: 警告: 戻りでポインタからキャスト無しに整数を作成しています [-Wint-conversion] return x; ^ ddd.c: 関数 ‘growTree’ 内: ddd.c:100:14: エラー: assignment to expression with array type x->sentence = dequeue(); なんとか解消しようとするのですが、どうしてもエラーが増えるばかりで、うまくいきませんでした。 どの部分をどのように直せばいいのか大変お手数ですが、教えていただけると助かります。 よろしくお願いいたします。 以下が実行したプログラムになっております。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define QUEUE_SIZE 100 /*キューの大きさ*/ /*配列でキューを表現する*/ int front, rear; char queue[3][50] = {"0b", "Ab", "Bb"}; char dequeue();/*キューからデータを取り出す*/ int next(int val);/*キューを配列で表現するとき、現在の次の配列のindexを返す*/ struct node{ char sentence[50];//値 struct node *left; //次のセルへのポインタ(左の子) struct node *right; //次のセルへのポインタ(右の子) }; int Gcount=0; void error(char *s);/*エラーを出力する*/ struct node* make_node();/*nodeをつくって返す*/ //void set_value_of_node(struct node* node,int a);/*nodeに値をセットする*/ struct node* growTree(int i, int k);/*深さiまで木を成長させ、そのルートを返す*/ void displayTree(struct node *node);/*node以下の部分木を表示する*/ int main(void){ struct node *root; int total=2 ; front = 0; rear = front + total + 1; root=growTree(total, 0); printf("\n\n\n前 順 表 示\n"); displayTree(root); return 0; } struct node* make_node(){/*nodeをつくって返す*/ struct node *p; if((p=(struct node*)malloc(sizeof(struct node ))) == NULL) error("メモリが足りません\n"); p->left =NULL; p->right =NULL; return(p); } //id set_value_of_node(struct node* node, int a)/*nodeに値をセットする*/ // //f(node == NULL)error("nodeが空です\n"); //ode->value=a; //rintf("%d ", node->value); // // void error(char *s){/*エラーを出力する*/ fprintf(stderr, s); exit(1); } /*キューからデータを取り出す*/ char dequeue(){ char *x; if(front == rear){ error("\nqueue is empty!!\n"); } x = queue[front]; front = next(front); return x; } /*キューを配列で表現するとき、現在の次の配列のindexを返す*/ int next(int val){ int next; next=(val+1)%QUEUE_SIZE; return(next); } struct node* growTree(int i, int k){/*深さiまで木を成長させ、そのルートを返す*/ /*課題1はここを書く*/ if(i == k) return NULL; k++; struct node *x; x = make_node(); x->sentence = dequeue(); x->left = growTree(i, k); x->right = growTree(i, k); return x; } void displayTree(struct node *node){/*node以下の部分木を表示する*/ /*課題2はここを書く*/ if(node == NULL) return; printf("%s\n", node->sentence); displayTree(node->left); displayTree(node->right); }

  • C言語 線形探索

    #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXBUFFERSIZE 256 struct LinkedListNode{ int data; struct LinkedListNode *next; }; struct LinkedList{ int node_num; struct LinkedListNode *head; }; LinkedList *LinkedListMake(char *filename) { FILE *fp; LinkedList *list; char buffer[MAXBUFFERSIZE]; /* ファイル有無のチェック */ if ((fp = fopen(filename, "r")) == NULL) { fprintf(stderr, "No Such File : %s\n", filename); exit (1); } list = LinkedListAlloc(); if (list == NULL) { /* 領域確保失敗 */ exit (0); /* 終了 */ } while (fgets(buffer, MAXBUFFERSIZE, fp)) { /* ファイル終端に到達するまでループ */ buffer[strlen(buffer) - 1] = '\0'; /* 改行文字を削除 */ LinkedListDataAdd(list, atoi(buffer)); } fclose(fp); return (list); } LinkedList *LinkedListAlloc(void) { LinkedList *list; list = (LinkedList *)malloc(sizeof(LinkedList)); if (list == NULL) { /* 領域確保失敗 */ return (NULL); } list->node_num = 0; list->head = NULL; return (list); } LinkedListNode *LinkedListDataAdd(LinkedList *list, int x) { LinkedListNode *ptr; /* 注目するノードへのポインタ */ LinkedListNode *prev; LinkedListNode *new_node; ptr = list->head; prev = NULL; while (ptr) { /* 終端ノードに到達するまでループ */ if (ptr->data < x) { prev = ptr; /* 直前ノードの更新 */ ptr = ptr->next; /* 注目ノードの更新 */ } else if (ptr->data == x) { /* x は登録済み */ return (NULL); } else { /* x を注目ノードの直前に追加 */ new_node = LinkedListNodeAlloc(); 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); } } /* 終端ノードに到達 */ /* x を終端に追加 */ new_node = LinkedListNodeAlloc(); if (new_node == NULL) { /* 領域確保失敗 */ exit (0); /* 終了 */ } new_node->data = x; new_node->next = NULL; /* new_node は新たな終端ノード */ if (prev != NULL) { /* list は少なくともひとつのノードを有している */ prev->next = new_node; /* 更新前の終端ノードの直後が new_node となる */ } else { /* list は空(ノードがひとつも含まれない) */ list->head = new_node; } list->node_num++; /* ノード総数の更新 */ return (new_node); } LinkedList *LinkedListSearch(LinkedList *list, int x)←ここがわかりません★ { for(i = 0; i < node_num)      ??? int main(int argc, char *argv[]) { int a, i, x; printf("xの値を入力"); scanf("%d", &x); LinkedListMake(argv[1]); LinkedListSearch(list, x); 連結リストに格納されたint型データから目的の値を線形探索するプログラムをつくってます。 連結リスト作成関数まではできたので、あと連結リストにおいて目的の値を線形探索する関数LinkedListSearchをつくればだいたい完成だと思うのですが、関数LinkedListSearchの作り方がわかりません。 引数で連結リストのポインタと目的値をとって、目的値が存在すればそのノードのポインタ、存在しない場合はNULLを返すようにするつもりです。 わかる方、是非とも教えてください! お願いいたします。

専門家に質問してみよう