二叉树先序遍历,中序遍历,后序遍历,层次遍历。

来源:互联网 发布:淘宝生活研究所 编辑:程序博客网 时间:2024/05/17 23:21

原理

  • 先序遍历
    又可叫前根序遍历先遍历根节点,再遍历根节点的左子树,然后遍历根节点的右子树。
  • 中序遍历
    又可叫中根序遍历,先遍历根节点的左子树,再遍历根节点,然后遍历根节点的右子树。
  • 后序遍历
    又可叫后根序遍历,先遍历根节点的左子树,再遍历根节点的右子树,然后遍历根节点
  • 层次遍历
    对整棵二叉树按从上到下,对每一层按从左到右的顺序进行遍历。这里我们需要借助队列:先访问节点的孩子节点也应比后访问节点的孩子节点先访问。故这就类似于队列先进先出的性质,每访问一个节点时,它的孩子节点(如果存在)就随着入队。

如图
这里写图片描述
先序遍历结果为——ABDHECFG
(首先从根节点开始,然后左节点,左节点成为根节点,然后再左节点,然后右节点(如果左子树遍历完后就遍历该根节点的右子树))
中序遍历结果为——HDBEAFCG
(当左节点被读取后,左节点被当作根节点)
后序遍历结果为——HDEBFGCA
(注意每个节点的左右子树必须遍历完)
层次遍历结果为——ABCDEFGH

这里写图片描述
先序遍历为 ABCDEFGHIJK
中序遍历为 CEDFBAHKJIG
后序遍历为 EFDCBKJIHGA

一些试题

已知部分遍历,求树或其他序列

操作

  • 迭代实现
    另外一种代码
//先序遍历void preOrderWithoutRecursion() {      if (!empty()) {        //使用一个栈,栈的先进后出实现功能        stack<BTNode*> s;          BTNode* p = root;        //先将根节点存入栈          s.push(p);        while (!s.empty()) {            //首先输出当前节点              cout << setw(4) << p->data;            //先存入右节点,栈的特性使之后出              if (p->rchild) s.push(p->rchild);            //后存入左节点,栈的特性使之先出              if (p->lchild) p = p->lchild;              else {       //p为输出节点,根节点输出后,应该为左节点,然后释放栈顶                  p = s.top();                  s.pop();              }          }          cout << endl;      }  }
//中序遍历void inOrderWithoutRecursion() {      if (!empty()) {        //利用栈的特性,先进后出。          stack<BTNode*> s;          BTNode* p = Root;          while (!s.empty() || p) {              if (p) {                //一直下降到最左边                  s.push(p);                  p = p->lchild;              }              else {                //当到底最左时,输出当前节点                p = s.top();                  s.pop();                  cout << setw(4) << p->data;                //如果该左节点被视为根节点并有右节点,p设为右节点,                  p = p->rchild;              }          }          cout << endl;      }  } 
//后序遍历  void postOrderWithoutRecursion() {      if (!empty()) {          //利用栈特性,进行操作        stack<BTNode*> s;          BTNode* p = Root;          while (p != NULL) {            //下降到最左边              s.push(p);              p = p->lchild;          }          while (!s.empty()) {              //判断当前该访问左节点还是右节点                BTNode* pLastVisit = p;            //最左节点入栈            p = s.top();              s.pop();            //当右节点为空或前节点,则说明该节点为左节点,直接输出            if (p->rchild == NULL || p->rchild == pLastVisit)                  cout << setw(4) << p->data;              //当左节点为前节点时,该点为根,该访问右节点            else if (p->lchild == pLastVisit) {                  s.push(p);                  p = p->rchild;                  s.push(p);                //如果右节点作为根节点有左右子树,则进行该操作                  while (p != NULL) {                      if (p->lchild != NULL)                         s.push(p->lchild);                      p = p->lchild;                  }              }          }          cout << endl;      }  }  
  • 递归实现
void preorder (node *p) {    if (p != NULL) {        cout << p->data << " ";        preorder(p->left);        preorder(p->right);    }}void inorder (node *p) {    if (p != NULL) {        inorder(p->left);        cout << p->data << " ";        inorder(p->right);    }}void postorder (node *p) {    if (p != NULL) {        postorder(p->left);        postorder(p->right);        cout << p->data << " ";    }}
  • 参考
    http://blog.csdn.net/zhangxiangdavaid/article/details/36634411
阅读全文
0 0
原创粉丝点击