以下のソースコードを用いて二分木を生成して、それをトラバーサルすると
昇順に表示されますが!
これを、用いて全ての節の子を(左の子と右の子)を交換する。
関数定義
void ReverseTree( struct BTREE *ptr);
を再帰的呼び出しによって実現してのですが!
どう考えればよいのでしょうか?
さらに、2分木の生成後に入力した整数値がリスト中にあるかどうかを
判定し、(存在すれば1、存在しなければ、0を関数値とする)
関数定義 int ExistTest(struct BTREE *ptr, searchdata);
を作成し動作を確認したいのですが!
ご教授して下さい。お願いします.

A 回答 (2件)

「再帰だ」ってるのに、あほうですね、私。

枝の処理を忘れてました。

それを直せたのだから、検索も簡単でしょう。

TraverseTree() が全てのノードを処理しているのに対し、検索はひとつでも
見つかれば、1を返せばよいのですから。

(1) 自分がその値であるか? そうなら、1を返しておしまい
(2) 無ければ、左にあるか? あれば、1を返しておしまい
(3) 無ければ、右にあるか? あれば、1を返しておしまい
(4) どこにもないので、0を返す

蛇足かもしれませんが、

>     } else if (ExistTest(ptr->left, searchdata)) {

と書いたのは

} else if (ExistTest(ptr->left, searchdata) != 0) {

と全く同じことです。
    • good
    • 0

TraverseTree() をじっと見れば、さほど難しくないと思うのだけどなあ。




> 全ての節の子を(左の子と右の子)を交換する。

void ReverseTree(struct BTREE *ptr)
{
  if (ptr == NULL) {
    return;
  } else {
    struct BTREE* tmp;
    tmp = ptr->left;
    ptr->left = ptr->right;
    ptr->right = tmp;
  }
}


> 2分木の生成後に入力した整数値がリスト中にあるかどうかを

int ExistTest(struct BTREE *ptr, int searchdata)
{
  if (ptr == NULL) {
    return 0;
  } else {
    if (ptr->data == searchdata) {
      return 1;
    } else if (ExistTest(ptr->left, searchdata)) {
      return 1;
    } else if (ExistTest(ptr->right, searchdata)) {
      return 1;
    } else {
      return 0;
    }
  }
}

# コンパイルや動作確認をしたわけではないので、自信無しです

この回答への補足

void ReverseTree (struct BTREE *ptr)
{
struct BTREE *workp;
if(ptr == NULL){
return;
}else{
workp = ptr->left;
ptr->left = ptr->right;
ptr->right = workp;
ReverseTree (ptr->left);
ReverseTree (ptr->right);
}
}

入れ替えとトラバーサルを行えばできました。
ありがとうございます。
検索は、奮闘中です.

補足日時:2001/12/08 01:22
    • good
    • 0
この回答へのお礼

入れ替えはワークを使用して入れ替えるのですが、
全ての節を行うには、という点がわかりません。

お礼日時:2001/12/08 01:13

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Qstructでvoid*型を利用して中身を動的に変化させる

構造体の中にvoid*型のポインタを作り、そこの中身を替えることでデータを変えたいと思っています。


struct DATA{
void* p;
}

struct PROF_1{
char* name;
int age;
}

struct PROF_2{
char* name;
int age;
int level;
}


void main(){
struct DATA data;
struct PROF_1 p1={"HATOYAMA", 60};
struct PROF_2 p2={"OBAMA", 60, 1};

data.p = p1;
printf("Name[%s] Age[%d]\n", (PROF_1)(data.p)->name, (PROF_1)(data.p)->age);

data.p = p2;
printf"Name[%s] Age[%d] Lv[%d]\n", (PROF_2)(data.p)->name, (PROF_2)(data.p)->age, (PROF_2)(data.p)->level);
}

このような感じで構造体の中にあるvoid*型のポインタの参照する場所を変えるだけで構造体の中身を変化させることが出来ないでしょうか?

構造体の中にvoid*型のポインタを作り、そこの中身を替えることでデータを変えたいと思っています。


struct DATA{
void* p;
}

struct PROF_1{
char* name;
int age;
}

struct PROF_2{
char* name;
int age;
int level;
}


void main(){
struct DATA data;
struct PROF_1 p1={"HATOYAMA", 60};
struct PROF_2 p2={"OBAMA", 60, 1};

data.p = p1;
printf("Name[%s] Age[%d]\n", (PROF_1)(data.p)->name, (PROF_1)(data.p)->age);

data.p = p2;
printf"Name...続きを読む

Aベストアンサー

>void*型のポインタの参照する場所を変えるだけで構造体の中身を変化させることが出来ないでしょうか?
できます。
使用する型がわかっているのであればunionで定義する方法もありますが。
struct DATA{
 int type;  // 入れている型
 union
 {
  struct PROF_1 data1;
  struct PROF_2 data2;
 }packet;  // 供用の定義
}
とか。
もちろんポインタも使用できます。

Qint select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)について

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識だとreadfds,writefdsが引数として与えられているとしても、
どちらかのfd_setのうち、一つでも動きがあればselect文は
抜けてしまうことになります。とすると、戻り値として
「readfds, writefds, exceptfds 中の 1 になっているビットの総数」
は常に1ということになってしまいます。しかし、総数というからには
複数同時に1になることもあるはずです。

私の認識が間違っているとは思うのですが、どう間違っているのかわかりません。
select文の動きについて詳しく教えていただけないでしょうか。
または良いページがあれば教えてください。

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きが...続きを読む

Aベストアンサー

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビットが一度にONになっているはずです。
一方、相手が、一切電文を送ってない状態で、selectを呼び出した場合は、何れかのビットがONになればリターンするので、そのときは、貴方が想像しているように
ビットの総数は1になる可能性が高いです。
従って、相手が電文を送る前にselectを呼び出すか、送った後にselectを呼び出すかは、その時のタイミングにより異なります。従って、ビット数の総和が常に1であるとは、考えない方が無難です。(1つのソケットしか使用しない場合は別ですが・・・)

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビ...続きを読む

Qchar *str; と char* str;

char *str; と char* str;
どっちも同じことを意味しているんですか?

Aベストアンサー

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染むのでしょう。ちなみにそういう風な人たちは

char *str1, *str2;

とは、書けない体になっています。

char* str1;
char* str2;


変数の宣言だと、C に慣れていれば、char* str というのはちょっと違和感があるのは
私も分かりますが、関数のプロトタイプ宣言だと、どちらの方がすっきりしますか?

extern char *memcpy(char *, const char *);

extern char* memcpy(char*, const char*);


# まあ、どっちが正しい、っていうんじゃ無いんですよね

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染む...続きを読む

Qchar* を渡したとき、不適切なPtrが出る問題

こんばんは。プログラムを勉強中の学生です。
詰まった部分があり、関連しそうな部分を勉強しましたが、問題が解決しなかったので、
こちらで質問させて頂きます。

今、とあるクラスで、

class Test{
........................................
public:
int Func1(char* str,){
unsigned int n = 0;
while(str != "\0"){ n += *str; str++;}          ←ここに<不適切なPtr>
return n % 3;
}

void Func2(char* str){
int i;
i = Calc(str);
.....................................
............................
}
};

のように宣言し、main()関数で、
int main(){

Test test;

test.Func2("ABC"); // Case1: エラーは起こらない

char s[]={"ABC"}; //Case2:不適切なPtrとなる。
test.Func2( s );

}


としていますが、上記のように、"ABC"を直接入れたときのみ、うまくいき、
他の方法で、char型のポインタを代入した際には、不適切なPtrと出てしまいます。

この原因を教えていただけないでしょうか?
最終的には、
cin >> s ;
などのように、キーボードから入力した値(文字列)を使いたいのですが、
現段階ではmain関数で "ABC"のように書かなければならず困っています。

こんばんは。プログラムを勉強中の学生です。
詰まった部分があり、関連しそうな部分を勉強しましたが、問題が解決しなかったので、
こちらで質問させて頂きます。

今、とあるクラスで、

class Test{
........................................
public:
int Func1(char* str,){
unsigned int n = 0;
while(str != "\0"){ n += *str; str++;}          ←ここに<不適切なPtr>
return n % 3;
}

void Func2(char* str){
...続きを読む

Aベストアンサー

>while(str != "\0")

while(*str != '\0')
じゃないですか?
つまり
while(*str)
でも良し。

Qstruct tanka_kosuu kosuu[10];の[10]て何

#include <stdio.h>
struct tanka_kosuu {
int tanka;
int kosuu;
int kingaku;
};
int main()
{
         struct tanka_kosuu kosuu[10];
       構造体宣言 構造体名  変数名
struct tanka_kosuu kari_nyuuryoku = {-1, 0, 0};
int nyuuryoku_kosuu = 0;
while(kari_nyuuryoku.tanka != 0){
scanf("%d %d", &kari_nyuuryoku.tanka,
&kari_nyuuryoku.kosuu);
kosuu[nyuuryoku_kosuu] = kari_nyuuryoku;
nyuuryoku_kosuu++;
}
return 0;
}
以上ですが、
 struct tanka_kosuu {
int tanka;
int kosuu;
int kingaku;
以上と
struct tanka_kosuu kosuu[10];は
 以下
int tanka;
int kosuu[10];
int kingaku;
 と同じ意味ですか?
 それとも
  int tanka[10];
int kosuu[10];
int kingaku[10]; 
 と同じ意味ですか?
int tanka[10];と
 int kingaku[10];の
 合計に[10]は必要ないですよね
以上すべて私の考え方が間違っていたならごめんなさい。
 以上よろしくお願いいたします。

#include <stdio.h>
struct tanka_kosuu {
int tanka;
int kosuu;
int kingaku;
};
int main()
{
         struct tanka_kosuu kosuu[10];
       構造体宣言 構造体名  変数名
struct tanka_kosuu kari_nyuuryoku = {-1, 0, 0};
int nyuuryoku_kosuu = 0;
while(kari_nyuuryoku.tanka != 0){
scanf("%d %d", &kari_nyuuryoku.tanka,
&kari_nyuuryoku.kosuu);
kosuu[nyuuryoku_kosuu] = kari_nyuuryoku;
nyuuryoku_kosuu++;
}
return 0;
}
以上です...続きを読む

Aベストアンサー

#1です。

>struct tanka_ data { ・・・・(1)
>  int tanka;
>  int kosuu;
>  int kingaku;
>};
・・・途中省略
>} これでいいでしょうか

(1)のところは、変えてはいけません。
struct tanka_kosuu { 
のままにして下さい。
他は、問題ありません。


このカテゴリの人気Q&Aランキング

おすすめ情報