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の条件を変えればいいのかと思い、いろいろ試してみたのですが、
左部分木には左側にしか葉がなく、右部分木には右にしか葉がないようなものしかできませんでした
もう何時間も悩んだのですが自分の知識では手づまりです
どうかよろしくお願いします。
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;
}
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);
}
}
と書き換えたのですが、まだエラーが出てしまいます…
No.4
- 回答日時:
No3さんの回答で気が点きましたが
私の
*p=x;
を
*p=createNode(x);
ではダメでしょうか?
その場合だとbtreeはループで毎回createNodeするべきではないです
コンパイルがうまくできませんでした
一応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;
}
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;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- JavaScript 画像の表示位置 3 2022/12/23 08:25
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- PHP php テーブルが作成できない 1 2022/11/17 23:41
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語で簡単なパックマンゲーム...
-
C言語で%を使わない余りの出し方
-
課題;素因数分解
-
線形補間法プログラム(C++)
-
intとlongは同じ?
-
unsigned型のビット構成を表示...
-
再起呼び出しの回数をカウント...
-
異なるn個の整数からr個の整数...
-
画像の拡大・縮小
-
直線補間について
-
2の補数を計算するプログラム
-
カードシャッフルのブログラム...
-
c言語プログラミングについて f...
-
C言語の問題
-
C言語
-
argvのNULLチェック
-
C言語のプログラムについて(...
-
以下のプログラムはOpenCVで画...
-
OpenCVによる4値化について
-
C++で表を作成したいのです ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
2の補数を計算するプログラム
-
intとlongは同じ?
-
再起呼び出しの回数をカウント...
-
C言語で%を使わない余りの出し方
-
迷路を脱出する経路探索プログ...
-
画像の拡大・縮小
-
分数の足し算をさせるプログラ...
-
C言語で簡単なパックマンゲーム...
-
C++で表を作成したいのです ...
-
条件が多い場合
-
複数の共有メモリの作成
-
ヒストグラム均等化処理プログラム
-
3のつく数と3の倍数を表示 C言語
-
argvのNULLチェック
-
乱数で交互に偶数、奇数が、、、。
-
プログラミングに関して
-
OpenCVによる4値化について
-
再帰処理をループ処理に変換
-
16bitで乱数を生成する方法
-
C++ Debug Errorについて教えて
おすすめ情報