Non-recursive binary tree traversal

GEC: Discuss gaming, computers and electronics and venture into the bizarre world of STGODs.

Moderator: Thanas

Post Reply
User avatar
Pu-239
Sith Marauder
Posts: 4727
Joined: 2002-10-21 08:44am
Location: Fake Virginia

Non-recursive binary tree traversal

Post by Pu-239 »

I'm doing trees in computer science, and I'm trying to figure out how to do traversals non-recursively. Here's my grossly messy code (in java). What obvious errors are there, and how could I make inorder more clean?


public Queue preOrder() {
TreeNode pointer = root;
Stack tr = new Stack();
Queue ret = new Queue();
boolean done = false;
//int counter = 0;
while (!done) {
if (pointer.getRight() != null) {
tr.push(pointer.getRight());
}
ret.enqueue(pointer.getValue());
//S.O.Pn((String)pointer.getValue()+ " " + counter);
//counter++;
if (pointer.getLeft() != null) {
pointer = pointer.getLeft();
} else if (tr.size() != 0) {
pointer = (TreeNode) tr.pop();
} else {
done = true;
}
}
return ret;
//return null;
}
public Queue inOrder() {
TreeNode pointer = root;
Stack tr = new Stack();
Queue ret = new Queue();
boolean done = false;
while (!done) {
if (pointer.getLeft() != null) {
tr.push(pointer);
pointer = pointer.getLeft();
} else if(pointer.getRight() != null){
ret.enqueue(pointer.getValue());
pointer = pointer.getRight();
} else if(tr.size() != 0){
ret.enqueue(pointer.getValue());
pointer = (TreeNode)tr.pop();
ret.enqueue(pointer.getValue());
if(pointer.getRight() != null){
pointer = pointer.getRight();
}else{
done = true;
}
}else if(tr.size() == 0 && pointer.getRight() == null && pointer.getLeft() == null){
S.O.Pn(((Integer)pointer.getValue()).intValue());
done = true;
}
}
return ret;
}

ah.....the path to happiness is revision of dreams and not fulfillment... -SWPIGWANG
Sufficient Googling is indistinguishable from knowledge -somebody
Anything worth the cost of a missile, which can be located on the battlefield, will be shot at with missiles. If the US military is involved, then things, which are not worth the cost if a missile will also be shot at with missiles. -Sea Skimmer


George Bush makes freedom sound like a giant robot that breaks down a lot. -Darth Raptor
User avatar
Crayz9000
Sith Apprentice
Posts: 7329
Joined: 2002-07-03 06:39pm
Location: Improbably superpositioned
Contact:

Post by Crayz9000 »

Ah, binary trees... been there, done that. Lemme clean up your code first and then I'll look through it a bit.
A Tribute to Stupidity: The Robert Scott Anderson Archive (currently offline)
John Hansen - Slightly Insane Bounty Hunter - ASVS Vets' Assoc. Class of 2000
HAB Cryptanalyst | WG - Intergalactic Alliance and Spoof Author | BotM | Cybertron | SCEF
User avatar
phongn
Rebel Leader
Posts: 18487
Joined: 2002-07-03 11:11pm

Post by phongn »

If you're writing code, use the code tag and indent.
User avatar
Crayz9000
Sith Apprentice
Posts: 7329
Joined: 2002-07-03 06:39pm
Location: Improbably superpositioned
Contact:

Post by Crayz9000 »

Well, here's the cleaned-up code.

Code: Select all

  public Queue preOrder()
  {
    TreeNode pointer = root;
    Stack tr = new Stack();
    Queue ret = new Queue();
    boolean done = false;		//int counter = 0;

    while (!done)
    {
      if (pointer.getRight() != null)
      {
        tr.push(pointer.getRight());
      }
      ret.enqueue(pointer.getValue());
      //S.O.Pn((String)pointer.getValue()+ " " + counter);
      //counter++;
      if (pointer.getLeft() != null)
      {
        pointer = pointer.getLeft();
      }
      else if (tr.size() != 0)
      {
        pointer = (TreeNode)tr.pop();
      }
      else
      {
        done = true;
      }
    }
    return ret;
    //return null;
  }

  public Queue inOrder()
  {
    TreeNode pointer = root;
    Stack tr = new Stack();
    Queue ret = new Queue();
    boolean done = false;
    while (!done)
    {
      if(pointer.getLeft() != null)
      {
        tr.push(pointer);
        pointer = pointer.getLeft();
      }
      else if(pointer.getRight() != null)
      {
        ret.enqueue(pointer.getValue());
        pointer = pointer.getRight();
      }
      else if(tr.size() != 0)
      {
        ret.enqueue(pointer.getValue());
        pointer = (TreeNode)tr.pop();
        ret.enqueue(pointer.getValue());
        if (pointer.getRight() != null)
        {
          pointer = pointer.getRight();
        }
        else
        {
          done = true;
        }
      }
      else if(tr.size() == 0 && pointer.getRight() == null && pointer.getLeft() == null)
      {
         System.out.println(((Integer)pointer.getValue()).intValue());
         done = true;
      }
    }
    return ret;
  }
I have a few things, though.

First, it doesn't pay to be lazy and write System.out.println() as S.O.Pn(). It can confuse the hell out of anyone looking at your code, and more importantly, Java won't have a clue what you're doing.

Secondly, you shouldn't have to do much typecasting if you know what sort of thing is getting returned. Did you write the TreeNode, Queue, and Stack classes? Or did your professor?
A Tribute to Stupidity: The Robert Scott Anderson Archive (currently offline)
John Hansen - Slightly Insane Bounty Hunter - ASVS Vets' Assoc. Class of 2000
HAB Cryptanalyst | WG - Intergalactic Alliance and Spoof Author | BotM | Cybertron | SCEF
User avatar
Pu-239
Sith Marauder
Posts: 4727
Joined: 2002-10-21 08:44am
Location: Fake Virginia

Post by Pu-239 »

The professor( teacher really, I'm in HS, gave the template, and we had to fill it in for Queue and Stack, and TreeNode was provided). I pulled it out straight from previous projects, and they were written for generic usage, hence the typecasting. We were actually supposed to do this w/ recursion which would be easy, but I wanted to see how it could be done w/o.

I made a wrapper for System.out.println with inner classes and such, so S.O.Pn() actually does work. People abbreviate like this when writing on overhead, so it's fairly obvious.

Clarification: I'm not concerned with the physical appearance of the code, but the size of inOrder, which is 50% more lines of code than preorder. I'm happy w/ preorder, but inorder just feels inefficient and buggy and more complicated than it has to be. Then there's postorder, which after spending many hours on inorder instead of required homework I'm not even going to bother trying to do nonrecursively.

ah.....the path to happiness is revision of dreams and not fulfillment... -SWPIGWANG
Sufficient Googling is indistinguishable from knowledge -somebody
Anything worth the cost of a missile, which can be located on the battlefield, will be shot at with missiles. If the US military is involved, then things, which are not worth the cost if a missile will also be shot at with missiles. -Sea Skimmer


George Bush makes freedom sound like a giant robot that breaks down a lot. -Darth Raptor
User avatar
Crayz9000
Sith Apprentice
Posts: 7329
Joined: 2002-07-03 06:39pm
Location: Improbably superpositioned
Contact:

Post by Crayz9000 »

Pu-239 wrote:We were actually supposed to do this w/ recursion which would be easy, but I wanted to see how it could be done w/o.
That's the usual excuse, but frankly, IMO it's often not worth it when you're in a class. Save the extra ideas for summer and winter breaks, when you don't have class committments to worry about.

As for the size of your code, the general rule is, if works, don't fix it. Fixing a perceived problem can often create more problems than it solves, although just cleaning up code is usually harmless.

I actually got into problems in my assembly language class last semester because I figured I'd do a bit more than I needed to on this one quiz/project. I inserted some code that I basically had memorized, but in doing so it did something to one of the registers and I never figured out what. Had to rewrite the whole damned thing because my apparently normal stack was anything but.



Uh, by the way, did you try flowcharting this? Getting a visualization of the problem generally helps when coding.
A Tribute to Stupidity: The Robert Scott Anderson Archive (currently offline)
John Hansen - Slightly Insane Bounty Hunter - ASVS Vets' Assoc. Class of 2000
HAB Cryptanalyst | WG - Intergalactic Alliance and Spoof Author | BotM | Cybertron | SCEF
User avatar
Pu-239
Sith Marauder
Posts: 4727
Joined: 2002-10-21 08:44am
Location: Fake Virginia

Post by Pu-239 »

Crayz9000 wrote: Uh, by the way, did you try flowcharting this? Getting a visualization of the problem generally helps when coding.
Sort of, sketched a tree on paper and jumped around, and sort of visualized a flowchart in my head. Most painful part is the off by one errors when actually coding.

ah.....the path to happiness is revision of dreams and not fulfillment... -SWPIGWANG
Sufficient Googling is indistinguishable from knowledge -somebody
Anything worth the cost of a missile, which can be located on the battlefield, will be shot at with missiles. If the US military is involved, then things, which are not worth the cost if a missile will also be shot at with missiles. -Sea Skimmer


George Bush makes freedom sound like a giant robot that breaks down a lot. -Darth Raptor
User avatar
phongn
Rebel Leader
Posts: 18487
Joined: 2002-07-03 11:11pm

Post by phongn »

You may want to write down your (flowcharted) algorithm in some detail before you go back and tackle the problem. Yeah, it takes time, and I hated doing that in HS as well, but it works.
Post Reply