Binary Tree program infinite loop

Hello, I'm running into what I presume is a logic problem. However, I can't seem to find it in my code. Please note that the readTree() and writeTree() functions are incorrect as I have not finished them. If you have any idea as to what might be causing this problem, I'd appreciate the feedback.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
#include <cstring>
#include <fstream>
using std::fstream;

struct animal{
  char text[100];
  animal* yes;
  animal* no;
};

void writeTree(animal *p, std::ostream &out){
  if(!p)
    return;
  else{
    out << p->text << " ";
    writeTree(p->yes, out);
    writeTree(p->no, out);
  }
}

void readTree(){

}

void deallocateTree(animal* root){
  if (!root)
    return;
  deallocateTree(root->yes);
  deallocateTree(root->no);
  delete root;
}

int main()
{
  animal* root= new animal; // initialize a "root" pointer named "animal* root"
  strcpy(root->text, "elephant");// set "root" to a newly created node; set its text to "elephant", pointers to 0s
  root->yes=NULL;
  root->no=NULL;

  char a[100];
  char q[100];
  char yesNo;

  while(true){// start a "while" loop that runs each cycle of the program
    cout << "Think of an animal. Enter Y to continue or N to exit." << endl;
    char playResponse;// invite the user to think of an animal which it will try //to guess
    cin >> playResponse;// await the user's response, and break out of the loop //if he declines
    //this is where I assume the problem arises. I can input a response but the //program doesn't move on. This only happens on the second iteration of the //while loop.
    if (toupper(playResponse)=='N')
      break;
    if (toupper(playResponse)!='Y'){
      cout << "That is not a valid response. Bye!" << endl;
      break;}

    animal* p=root;
    while (true){// start a loop to traverse the binary tree
      if (p->yes==NULL){// if p->yes is 0...
        for (int i=0; p->text[i]!='\0'; i++)//...print p->text as the guessed animal
          cout << p->text[i];

        cout << "\nIs this the animal you were thinking of? (y/n)" << endl;
        char YNResponse;
        cin >> YNResponse;
        cin.ignore();

        if (toupper(YNResponse)=='Y'){
          cout << "Got it!" << endl;// if correct
          break;
        }

        cout << "What animal was it?" << endl;
        cin.getline(a, sizeof(a));//...store in "char a[100]"

        cout << "What Yes or No question differentiates "; // ask what yes/no question differentiates "p->text" from "a"...
        for (int i=0; p->text[i]!='\0';i++){ cout << p->text[i];}
        cout << " from ";
        for (int i=0; a[i]!='\0';i++){cout << a[i];}
        cout << "?" << endl;
        cin.getline(q, sizeof(q));//...store in "char q[100]"

        cout << "Is the answer Yes or No? (y/n)" << endl;// ask which response is correct for "a" -- yes or no...
        cin >> yesNo;//...store in "char yesNo"

        animal* y=new animal;// create two new nodes, names "y" and "n"
          strcpy(y->text,"");
        animal* n=new animal;
          strcpy(n->text, "");

        if (toupper(yesNo)=='Y'){// if the correct response for "a" is yes...
          strcpy(y->text, a);// copy "a" into y->text
          strcpy(n->text, p->text);// copy p->text into n->text
        }
        else if(toupper(yesNo)=='N'){// else if the correct response is no...
          strcpy(n->text, a);// copy "a" into n->text
          strcpy(y->text, p->text);// copy p->text into y->text
        }
        else{
          cout << "Not a valid answer. Starting over." << endl;
          break;
        }
        strcpy(p->text, q);// copy "q" into p->text
        y->yes=NULL;// set y->yes, n->yes, y->no, and n->no to 0
        n->yes=NULL;
        y->no=NULL;
        n->no=NULL;

        p->yes=y;// set p->yes to y and p->no to n
        p->no=n;
        break;// break from loop
      }
      else if (!p->yes){// else if p->yes is not 0
        cout << p->text << " ?" << endl;// print p->text as a question
        cout << "Answer y/n" << endl;// ask for a yes/no reply...
        cin >> yesNo;//...store in "char yesNo"

        if (toupper(yesNo)=='Y')
          p=p->yes;// if "yes", set p to p->yes
        else if (toupper(yesNo)=='N')
          p=p->no;// else if "no", set p to p->no
      }
    }
  }
  //fstream tree ("D:/animal.dat", std::ios::out|std::ios::binary);
  //writeTree(root, tree);
  //deallocateTree(root);// reclaim memory
}
closed account (48T7M4Gy)
If you think there is a problem why not add a few diagnostic lines eg cout << "got to this line or whatever\n"; or setup break points and see where the offending line(s) is.

Debugging is half the fun of getting a program to run. The problem you have is you have gone too far before testing. Now you have 131 lines and no idea which line started the problem so it can be narrowed down very easily.

Also you na print out diagnostic lines with variable values or use more more sophisticated, but generally unnecessary, formal debugging tools.

Also, you should be able to show in this case your inputs, expected outputs and what you actually got.
Last edited on
I did. It's on line 52 on the second iteration. I mentioned that in the comment.

I don't really have a lot of experience with debugging tools but I'll see if I can find something to help.

I was just hoping someone else could try running this and be a second pair of eyes. I've been going over the logic pretty extensively but still can't find the problem.
closed account (48T7M4Gy)
I ran your program before I made the comment above. The difficulty is your intent is not clear. Good software is initially planned using pseudocode or some other process so when it goes off the rails the programmer pretty much know where, how and why even if the technicalities may need to be researched with assistance. So far all you know is it doesn't work and you want someone to fix it.

If you showed your pseudocode then the situation would be clearer even though there may be a fault in the implementation.

It's up to you but often, and more likely, the logic of just a program on its own will not divulge the underlying logic the program is intended to follow. The fact that you code compiles means that you have written logical/compileable/runnable code. But you're saying the machine is not doing what you want ... there is a message there!

Looking at your code, I suggest you flow chart it because if you haven't used any other method, my observation is you have a very tangled set of questions and pathways.
Topic archived. No new replies allowed.