树的遍历总结

前序遍历(DLR)
  前序遍历也叫做 先根遍历、先序遍历,可记做根左右。
  前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。
  若 二叉树为空则结束返回,否则:
  (1)访问根结点。 
  (2)前序遍历左子树
  (3)前序遍历右子树 。
  需要注意的是:遍历左右子树时仍然采用前序遍历方法。
  如图所示二叉树
   树的遍历总结

  前序遍历,也叫先根遍历,遍历的顺序是,根,左子树,右子树
  遍历结果:ABDECF
   中序遍历,也叫 中根遍历,顺序是 左子树,根,右子树
  遍历结果:DBEAFC
   后序遍历,也叫 后根遍历,遍历顺序,左子树,右子树,根

  遍历结果:DEBFCA

C语言版本

  树中节点结构为:

  typedef struct TreeNode

  {

  int data;

  TreeNode * left;

  TreeNode * right;

  TreeNode * parent;

  }TreeNode;

  void pre_order(TreeNode * Node)

  {

  if(Node != NULL)

  {

  printf("%d ", Node->data);

  pre_order(Node->left);

  pre_order(Node->right);

  }

    }

  调用时: pre_order(Root); //Root为树的根

中序遍历(LDR)

中序遍历也叫做中根遍历,可记做左根右。

  中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。在遍历左、右子树时,仍然先遍历左子树,再访问根结点,最后遍历右子树。即:

  若二叉树为空则结束返回,

  否则:

  (1)中序遍历左子树。

  (2)访问根结点。

  (3)中序遍历右子树。

  注意的是:遍历左右子树时仍然采用中序遍历方法。

  即左子树(B D E)还是左边开始(D),然后是(B),再是右边(E),完后经过(A),接着右子树(C F) 还是左边开始(F),再是中间(C),

  即顺序是DBEAFC

  中序遍历的时间复杂度为:O(n)。

  如果一棵二叉排序树的节点值是数值,中序遍历的结果为升序排列的数组。可以利用该性质检测一棵树是否为二叉排序数。

c++版本

  树中节点结构为:

  typedef struct TreeNode

  {

  int data;

  TreeNode * left;

  TreeNode * right;

  TreeNode * parent;

  }TreeNode;

  void middle_order(TreeNode * Node)

  {

  if(Node != NULL)

  {

  middle_order(Node->left);

  printf("%d ", Node->data);

  middle_order(Node->right);

  }

  }

  调用时: middle_order(Root); //Root为树的根

后序遍历

后序遍历是二叉树遍历的一种。后序遍历指在访问根结点、遍历左子树与遍历右子树三者中,首先遍历左子树,然后遍历右子树,最后遍历访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。后序遍历有递归算法和非递归算法两种。

算法描述:

  (1)若二叉树为空,结束

  (2)后序遍历左子树

  (3)后序遍历右子树

  (4)访问根结点

  遍历结果:DEBFCA

c语言描述 (递归)

  struct btnode

  {

  int d;

  struct btnode *lchild;

  struct btnode *rchild;

  };

  void postrav(struct btnode *bt)

  {

  if(bt!=NULL)

  {

  postrav(bt->lchild);

  postrav(bt->rchild);

  printf("%d ",bt->d);

  }

  }

非递归算法 

算法1(c语言描述):

  void postrav1(struct btnode *bt)

  {

  struct btnode *p;

  struct

  {

  struct btnode *pt;

  int tag;

  }st[MaxSize];

  }

  int top=-1;

  top++;

  st[top].pt=bt;

  st[top].tag=1;

  while(top>-1) /*栈不为空*/

  {

  if(st[top].tag==1) /*不能直接访问的情况*/

  {

  p=st[top].pt;

  top--;

  if(p!=NULL)

  {

  top++; /*根结点*/

  st[top].pt=p;

  st[top].tag=0;

  top++; /*右孩子结点*/

  st[top].pt=p->p->rchild;

  st[top].tag=1;

  top++; /*左孩子结点*/

  st[top].pt=p->lchild;

  st[top].tag=1;

  }

  }

  if(st[top].tag==0) /*直接访问的情况*/

  {

  printf("%d ",st[top].pt->d);

  top--;

  }

  }

  }

  算法2:

  void postrav2(struct btnode *bt)

  {

  struct btnode *st[MaxSize],*p;

  int flag,top=-1;

  if(bt!=NULL)

  {

  do

  {

  while(bt!=NULL)

  {

  top++;

  st[top]=bt;

  bt=bt->lchild;

  }

  p=NULL;

  flag=1;

  while(top!=-1 && flag)

  {

  bt=st[top];

  if(bt->rchild==p)

  {

  printf("%d ",bt->d);

  top--;

  p=bt;

  }

  else

  {

  bt=bt->rchild;

  flag=0;

  }

  }

  }while(top!=-1)

  printf("\n");

  }

  }

扩展:

已知一棵二叉树的前序遍历序列和中序遍历序列,可以唯一确定这棵二叉树。已知一棵二叉树的后序遍历序列和中序遍历序列,也可以唯一确定这棵二叉树。但是,已知一棵二叉树的前序遍历序列和后序遍历序列,不能唯一确定这棵二叉树。

你可能感兴趣的:(遍历)