程序3——二叉树的前中后层序遍历

定义数据结构

typedef struct BiTree {
  int data;
  struct BiTree *lchild, *rchild;
} BiTree;

前序遍历

void PreOder(BiTree *T) {
  if( T == null ) {
    return;
  }
  stack s;
  BiTree *t = T;
  while( t != null || !s.isEmpty() ) {
    if (t != null) {
      print(t->data);
      s.push(t);
      t = t->lchild;
    }
    else {
      t = s.pop();
      t = t->rchild;
    }
  }
}

中序遍历

中序遍历的非递归与前序的差不多,再写一下,熟练熟练。

void inOder(BiTree *T) {
  if ( T == null ) {
    return;
  }
  stack s;
  BiTree *t = T;
  while ( t != null || !s.isEmpty() ) {
    if (t != null) {
      s.push(t);
      t = t->lchild;
    }
    else {
      t = s.pop();
      print(t->data);
      t = t->rchild;
    }
  }
}

后序遍历

后序遍历相对于前两种来说,要复杂一些。要么使用两个栈,要么就要一些稍复杂、晦涩的逻辑。

void postOrder(BiTree *T) {
  if (T == null) {
    return;
  }
  stack s, out;
  BiTree *t = T;
  s.push(t);
  while( !s.isEmpty() ) {
    t = s.pop();;
    out.push(t);
    if (t->lchild != null) {
      s.push(t->lchild);
    }
    if (t->rchild != null) {
      s.push(t->rchild);
    }
  }
  while( !out.isEmpty() ) {
    t = out.pop();
    print(t->data);
  }
}

使用两个栈,逻辑比较简单,但是却多用了一点点内存,下面的代码只使用一个栈实现。

void postOrder(BiTree *T) {
  if ( T == null ) {
    return;
  }
  stack s;
  BiTree *t = T;
  BiTree *pre = null;
  while ( t != null || !s.isEmpty() ) {
    if (t != null) {
      s.push(t);
      t = t->lchild;
    }
    else if ( s.top()->rchild == pre) { pre = s.pop(); print(pre->data); } else { t = s.top()->rchild;
      pre = null;
    }
  }
}

这种实现比较难搞懂的就是这个pre,这个pre记录着上次访问过(打印出)的节点,程序刚开始执行时,自然pre=null。当栈顶元素的rchild等于pre,说明栈顶元素的rchild已经访问完了,栈顶元素就可以出栈了;如果不等于pre,则需要访问其rchild。不要忘了,二叉树的定义就是一个递归定义,左右子树都是二叉树。这样可以将,s.top()->rchild看成是T,重新执行。

层序遍历

层序遍历使用就不是栈了,而是队列

void levelOrder(BiTree *T) {
  if ( T == null ) {
    return;
  }
  queue q;
  BiTree *t = T;
  q.enQueue(t);
  while (!q.isEmpty()) {
    t = q.deQueue();
    print(t->data);
    if (t->lchild)
      q.enQueue(t->lchild);
    if (t->rchild)
      q.enQueue(t->rchild);
  }
}

层序遍历比较简单,下面对其变化一下。要求:逐层打印节点。
这时需要记录孩子节点的个数。

void levelOrder(BiTree *T) {
  if (T == null) {
    return;
  }
  BiTree *t = T;
  queue q;
  int curCount = 1;
  int nextCount = 0;
  q.enQueue(t);
  while (!q.isEmpty()) {
    t = q.deQueue();
    print(t->data);
    curCount--;
    if(t->lchild) {
      q.enQueue(t->lchild);
      nextCount++;
    }
    if(t->rchild) {
      q.enQueue(t->rchild);
      nextCount++;
    }
    if(curCount == 0) {
      print("\n");
      curCount = nextCount;
      nextCount = 0;
    }
  }
}

你可能感兴趣的:(二叉树,前中后层序遍历)