当前位置:   article > 正文

二叉树遍历(循环和递归)_二叉查找树结构使用循环遍历

二叉查找树结构使用循环遍历

递归

1.前序遍历

  1. void preorder(BinTree *T)
  2. {
  3. if(T==NULL)
  4. return;
  5. cout << T->data;
  6. preorder(T->left);
  7. preorder(T->right);
  8. }

2.中序遍历

  1. void inoeder(BinTree *T)
  2. {
  3. if(T == NULL)
  4. return;
  5. inoeder(T->left);
  6. cout << T->data;
  7. inoeder(T->right);
  8. }

3.后序遍历

  1. void postorder(BinTree *T)
  2. {
  3. if (T==NULL)
  4. return;
  5. postorder(T->left);
  6. postorder(T->right);
  7. cout << T->data;
  8. }


循环

1.前序遍历 法一

  1. void preorder(BinTree *T)
  2. {
  3. //空树,直接返回
  4. if(T==NULL)
  5. return;
  6. //定义一个存放二叉树节点的栈结构
  7. stack<BinTree*>s;
  8. BinTree *pcur;
  9. pcur = T;
  10. //循环遍历二叉树直到根节点为空或者栈为空
  11. while (pcur || !s.empty())
  12. {
  13. if (pcur)
  14. {
  15. cout << pcur->data;
  16. s.push(pcur);
  17. pcur = pcur->left;
  18. }else
  19. {
  20. //当根节点为空时,说明左子树已遍历完,通过取出栈顶结点,来访问根节点的右子树
  21. pcur = s.top();
  22. s.pop();
  23. pcur = pcur->right;
  24. }
  25. }
  26. }

法二(自己)

  1. void preOrder(binTree * root)
  2. {
  3. if(root==NULL)
  4. return;
  5. stack<binTree*> stackTree;
  6. binTree* curTree;
  7. stackTree.push(root);
  8. while(!stackTree.empty())
  9. {
  10. curTree=stackTree.top();
  11. stackTree.pop();
  12. cout<<curTree->value;
  13. if(curTree->right!=NULL)
  14. stackTree.push(curTree->right);
  15. if(curTree->left!=NULL)
  16. stackTree.push(curTree->left);
  17. }
  18. }

2.中序遍历

  1. void inorder(BinTree *T)
  2. {
  3. if(T == NULL)
  4. return;
  5. stack<BinTree*>s;
  6. BinTree *pcur;
  7. pcur = T;
  8. while (pcur || !s.empty())
  9. {
  10. if (pcur)
  11. {
  12. //根节点非空,入栈,继续遍历左子树直到根节点为空
  13. s.push(pcur);
  14. pcur = pcur->left;
  15. }else
  16. {
  17. //根节点为空,说明左子树已经遍历完,弹出根节点打印,通过根节点访问右子树
  18. pcur = s.top();
  19. s.pop();
  20. cout << pcur->data;
  21. pcur = pcur->right;
  22. }
  23. }
  24. }

3.后序遍历

法一,会改变原来的内容

  1. void postorder2(BinTree *T)
  2. {
  3. if(T == NULL)
  4. return;
  5. stack<BinTree*>s;
  6. s.push(T);
  7. BinTree *pcur;
  8. pcur = NULL;
  9. while (!s.empty())
  10. {
  11. pcur = s.top();
  12. if (pcur->left == NULL && pcur->right == NULL)
  13. {
  14. cout << pcur->data;
  15. s.pop();
  16. }else
  17. {
  18. //注意右孩子先入栈左孩子后入栈,这样再次循环时左孩子节点才先出栈
  19. if(pcur->right)
  20. {
  21. s.push(pcur->right);
  22. pcur->right = NULL;
  23. }
  24. if (pcur->left)
  25. {
  26. s.push(pcur->left);
  27. pcur->left = NULL;
  28. }
  29. }
  30. }
  31. }

法二,不用辅助栈,不改变内容

  1. void PostOrderWithoutRecursion(BTNode* root)
  2. {
  3. if (root == NULL)
  4. return;
  5. stack<btnode*> s;
  6. //pCur:当前访问节点,pLastVisit:上次访问节点
  7. BTNode* pCur, *pLastVisit;
  8. pCur = root;
  9. pLastVisit = NULL;
  10. //先把pCur移动到左子树最下边
  11. while (pCur)
  12. {
  13. s.push(pCur);
  14. pCur = pCur->lchild;
  15. }
  16. while (!s.empty())
  17. {
  18. //走到这里,pCur都是空,并已经遍历到左子树底端(看成扩充二叉树,则空,亦是某棵树的左孩子)
  19. pCur = s.top();
  20. s.pop();
  21. //一个根节点被访问的前提是:无右子树或右子树已被访问过
  22. if (pCur->rchild == NULL || pCur->rchild == pLastVisit)
  23. {
  24. cout << pCur->data;
  25. //修改最近被访问的节点
  26. pLastVisit = pCur;
  27. }
  28. /*这里的else语句可换成带条件的else if:
  29. else if (pCur->lchild == pLastVisit)//若左子树刚被访问过,则需先进入右子树(根节点需再次入栈)
  30. 因为:上面的条件没通过就一定是下面的条件满足。仔细想想!
  31. */
  32. else
  33. {
  34. //根节点再次入栈
  35. s.push(pCur);
  36. //进入右子树,且可肯定右子树一定不为空
  37. pCur = pCur->rchild;
  38. while (pCur)
  39. {
  40. s.push(pCur);
  41. pCur = pCur->lchild;
  42. }
  43. }
  44. }
  45. cout << endl;
  46. }
法三。不用辅助栈,不改变内容,推荐
  1. void beh_traverse(BTree pTree)
  2. {
  3. PSTACK stack = create_stack(); //创建一个空栈
  4. BTree node_pop; //用来保存出栈的节点
  5. BTree pCur; //定义指针,指向当前节点
  6. BTree pPre = NULL; //定义指针,指向上一各访问的节点
  7. //先将树的根节点入栈
  8. push_stack(stack,pTree);
  9. //直到栈空时,结束循环
  10. while(!is_empty(stack))
  11. {
  12. pCur = getTop(stack); //当前节点置为栈顶节点
  13. if((pCur->pLchild==NULL && pCur->pRchild==NULL) ||
  14. (pPre!=NULL && (pCur->pLchild==pPre || pCur->pRchild==pPre)))
  15. {
  16. //如果当前节点没有左右孩子,或者有左孩子或有孩子,但已经被访问输出,
  17. //则直接输出该节点,将其出栈,将其设为上一个访问的节点
  18. printf("%c ", pCur->data);
  19. pop_stack(stack,&node_pop);
  20. pPre = pCur;
  21. }
  22. else
  23. {
  24. //如果不满足上面两种情况,则将其右孩子左孩子依次入栈
  25. if(pCur->pRchild != NULL)
  26. push_stack(stack,pCur->pRchild);
  27. if(pCur->pLchild != NULL)
  28. push_stack(stack,pCur->pLchild);
  29. }
  30. }
  31. }

4.层次遍历

  1. void leveltraversal(BinTree *T)
  2. {
  3. queue<BinTree*> s;
  4. s.push(T);
  5. BinTree* pcur;
  6. while (!s.empty())
  7. {
  8. pcur=s.front();
  9. cout<<pcur->data;
  10. s.pop();
  11. if (pcur->left)
  12. {
  13. s.push(pcur->left);
  14. }
  15. if (pcur->right)
  16. {
  17. s.push(pcur->right);
  18. }
  19. }
  20. }
分层遍历二叉树,即从上到下按层次访问该树,每一层单独输出一行
  1. void leveltraversal3(BinTree *T)
  2. {
  3. if(T == NULL)
  4. return;
  5. queue<BinTree*>s;
  6. s.push(T);
  7. BinTree *pcur,*last,*nlast;
  8. last = T;
  9. nlast = NULL;
  10. while (!s.empty())
  11. {
  12. pcur = s.front();
  13. cout << pcur->data;
  14. s.pop();
  15. if (pcur->left)
  16. {
  17. s.push(pcur->left);
  18. nlast = pcur->left;
  19. }
  20. if (pcur->right)
  21. {
  22. s.push(pcur->right);
  23. nlast = pcur->right;
  24. }
  25. if (last == pcur)
  26. {
  27. cout << endl;
  28. last = nlast;
  29. }
  30. }
  31. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/275032
推荐阅读
相关标签
  

闽ICP备14008679号