実現したいこと
赤黒木かどうかの判定基準である「赤い節点の子は黒い節点」と「根から葉までの黒い節点の数が一致」という二つの条件をそれぞれ判定するプログラム「check_color」と「setten」の作成
発生している問題
以下のように作成したところ、どのような木を入力してもcheck_color()は1,setten()は0を毎回出力するようになってしまっています。どこがおかしいのでしょうか。
該当のソースコード
C
1#include<stdio.h> 2#include<stdlib.h> 3char buf[128]; 4struct map { int id; char name[32];}; 5typedef struct map datatype; /* ← 格納するデータは構造体 student */ 6struct rb_node { datatype data; struct rb_node *left, *right; int black; }; 7 8struct rb_node* get_rbtree() { 9 struct rb_node *t; 10 char c; 11/* ドットだけなら葉 (NULL) を返す */ 12 if(fgets(buf,sizeof(buf),stdin)==NULL || buf[0]=='.') 13 return NULL; 14 else { 15/* ドットでなければ節点を表す構造体のアドレス t を用意 */ 16 t = (struct rb_node*)malloc(sizeof(struct rb_node)); 17/* 色を表す文字を c に、id、名前を t->data に格納 */ 18 sscanf(buf,"[%c]%d,%[^,]",&c,&t->data.id,t->data.name); 19/* 色の文字が b なら 1、r なら 0 */ 20 t->black = (c=='b'); 21/* 左の子を t->left に、右の子を t->right に格納 */ 22 t->left = get_rbtree(); t->right = get_rbtree(); 23/* t を返す */ 24 return t; 25 } 26} 27int is_red(struct rb_node *t){ 28 return(t != NULL && !t->black); 29} 30 31int check_color(struct rb_node *t){//条件 32 if(is_red(t) == 1){ 33 if(is_red(t->left) == 1 || is_red(t->right) == 1){//赤い節点の子が赤ならば 34 return 0;//条件に反するので0を返す 35 } 36 } 37 check_color(t->left); 38 check_color(t->right); 39 return 1;//条件に適するので1を返す 40} 41 42int savecount; 43int setten(struct rb_node *t, int count){//条件3 44 count += t->black; 45 if(!t->left && !t->right){ 46 if(savecount==-1){ 47 savecount = count; 48 return 1; 49 }else if(savecount != count){ 50 return 0; 51 }else{ 52 return 1; 53 } 54 } 55 if(t->left){ 56 if(setten(t->left,count)==0){ 57 return 0; 58 } 59 } 60 if(t->right){ 61 if(setten(t->right,count)==0){ 62 return 0; 63 } 64 } 65 return 1; 66} 67 68int is_rbtree(struct rb_node *t) {//赤黒木なら1を返す 69 int a = 1; 70 int b = 1; 71 a = check_color(t); 72 b = setten(t, 0); 73 if(a == 1 && b == 1){//条件2,3に適するならば 74 return 1; 75 }else{//条件2,3に反するものがあるならば 76 return 0; 77 } 78} 79 80int main() { 81 struct rb_node *t = get_rbtree(); 82 if(is_rbtree(t)) printf("Yes.\n"); 83 else printf("No.\n"); 84 return 0; 85}
入出力例
入力
[b]10567,nagano
[r]10234,tokyo
[b]10123,kanagawa
.
.
[b]10345,chiba
.
[r]10456,aomori
.
.
[b]10678,ishikawa
.
.
出力
Yes.
入力
[b]10567,nagano
[r]10234,tokyo
[r]10123,kanagawa
.
.
.
[r]10456,aomori
.
.
出力
No.(check_colorに違反)
入力
[b]chiba
[b]kanagawa
.
[r]tokyo
.
.
[b]10678,ishikawa
[b]10456,aomori
.
[r]10567,nagano
.
.
[r]10890,kumamoto
.
.
出力
No.(setten()に違反)
回答1件
あなたの回答
tips
プレビュー