树得广度优先和深度优先遍历
来源:互联网 发布:软件测试原则 编辑:程序博客网 时间:2024/06/05 15:11
source:http://steven-hong.javaeye.com/blog/493665
图的深度优先搜索法是树的先根遍历的推广,它的基本思想是:从图G的某个顶点v0出发,访问v0,然后选择一个与v0相邻且没被访问过的顶点vi访问,再 从vi出发选择一个与vi相邻且未被访问的顶点vj进行访问,依次继续。如果当前被访问过的顶点的所有邻接顶点都已被访问,则退回到已被访问的顶点序列中 最后一个拥有未被访问的相邻顶点的顶点w,从w出发按同样的方法向前遍历,直到图中所有顶点都被访问。图的广度优先搜索是树的按层次遍历的推广,它的基本思想是:首先访问初始点vi,并将其标记为已访问过,接着访问vi的所有未被访问过的邻接点 vi1,vi2, …, vi t,并均标记已访问过,然后再按照vi1,vi2, …, vi t的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过,依次类推,直到图中所有和初始点vi有路径相通的顶点都被访问过为止。二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。为了方便程序验证,首先构造一个如图所示的二叉树。 源码:/*************************** bintree.h文件 *****************************/#ifndef _BINTREE_H#define _BINTREE_H template <class T>class CBintree{public: CBintree(); bool Depth_RF();//先根深度遍历 bool Depth_RM();//中根深度遍历 bool WidthFS(); //层次遍历protected:private: struct TreeNode { T va; TreeNode *plchild; TreeNode *prchild; }; TreeNode *m_pBintree;};#endif template <class T>CBintree<T>::CBintree(){ m_pBintree = new TreeNode; TreeNode *pNode2 = new TreeNode; TreeNode *pNode3 = new TreeNode; TreeNode *pNode4 = new TreeNode; TreeNode *pNode5 = new TreeNode; TreeNode *pNode6 = new TreeNode; TreeNode *pNode7 = new TreeNode; m_pBintree->va = (T)1; m_pBintree->plchild = pNode2; m_pBintree->prchild = pNode3; pNode2->va = (T)2; pNode2->plchild = pNode4; pNode2->prchild = pNode5; pNode3->va = (T)3; pNode3->plchild = NULL; pNode3->prchild = pNode6; pNode4->va = (T)4; pNode4->plchild = NULL; pNode4->prchild = NULL; pNode5->va = (T)5; pNode5->plchild = pNode7; pNode5->prchild = NULL; pNode6->va = (T)6; pNode6->plchild = NULL; pNode6->prchild = NULL; pNode7->va = (T)7; pNode7->plchild = NULL; pNode7->prchild = NULL;} template <class T>bool CBintree<T>::Depth_RF() //先根深度遍历{ cout << "先根遍历序列:\n"; stack <TreeNode> s; s.push(*m_pBintree); while (!s.empty()) { TreeNode node_s = s.top(); cout << node_s.va << "\n"; s.pop(); if (node_s.prchild != NULL) { s.push(*node_s.prchild); } if (node_s.plchild != NULL) { s.push(*node_s.plchild); } } return true;} template <class T>bool CBintree<T>::Depth_RM() //中根深度遍历{ cout << "中根遍历序列:\n"; stack <TreeNode> s; TreeNode *pNode = m_pBintree; while (pNode != NULL || !s.empty()) { while (pNode != NULL) { s.push(*pNode); pNode = pNode->plchild; } if (!s.empty()) { TreeNode node_s = s.top(); cout << node_s.va << "\n"; s.pop(); pNode = node_s.prchild; } } return true;} template <class T>bool CBintree<T>::WidthFS() //层次遍历{ cout << "层次遍历序列:\n"; queue <TreeNode> q; q.push(*m_pBintree); while (!q.empty()) { TreeNode *pNode = &q.front(); cout << pNode->va << "\n"; if (pNode->plchild != NULL) { q.push(*pNode->plchild); } if (pNode->prchild != NULL) { q.push(*pNode->prchild); } q.pop(); } return true;} /************************ main.cpp 文件 ****************************/#include <iostream>#include <stack>#include <queue>using namespace std; #include "bintree.h" int main(){ CBintree <int> bt; bt.Depth_RF(); bt.Depth_RM(); bt.WidthFS(); return 0;}/***************** 教科书标准算法及优化算法(转)*******************/1.先序遍历非递归算法void PreOrderUnrec(Bitree *t){ Stack s; StackInit(s); Bitree *p=t; while (p!=NULL || !StackEmpty(s)) { while (p!=NULL) //遍历左子树 { visite(p->data); push(s,p); p=p->lchild; } if (!StackEmpty(s)) //通过下一次循环中的内嵌while实现右子树遍历 { p=pop(s); p=p->rchild; }//endif }//endwhile }2.中序遍历非递归算法void InOrderUnrec(Bitree *t){ Stack s; StackInit(s); Bitree *p=t; while (p!=NULL || !StackEmpty(s)) { while (p!=NULL) //遍历左子树 { push(s,p); p=p->lchild; } if (!StackEmpty(s)) { p=pop(s); visite(p->data); //访问根结点 p=p->rchild; //通过下一次循环实现右子树遍历 }//endif }//endwhile}3.后序遍历非递归算法typedef enum{L,R} tagtype;typedef struct{ Bitree ptr; tagtype tag;}stacknode;typedef struct{ stacknode Elem[maxsize]; int top;}SqStack;void PostOrderUnrec(Bitree t){ SqStack s; stacknode x; StackInit(s); p=t; do { while (p!=null) //遍历左子树 { x.ptr = p; x.tag = L; //标记为左子树 push(s,x); p=p->lchild; } while (!StackEmpty(s) && s.Elem[s.top].tag==R) { x = pop(s); p = x.ptr; visite(p->data); //tag为R,表示右子树访问完毕,故访问根结点 } if (!StackEmpty(s)) { s.Elem[s.top].tag =R; //遍历右子树 p=s.Elem[s.top].ptr->rchild; } }while (!StackEmpty(s));}//PostOrderUnrec 4.前序最简洁非递归算法void PreOrderUnrec(Bitree *t){ Bitree *p; Stack s; s.push(t); while (!s.IsEmpty()) { s.pop(p); visit(p->data); if (p->rchild != NULL) s.push(p->rchild); if (p->lchild != NULL) s.push(p->lchild); }} 5.后序算法之二void BT_PostOrderNoRec(pTreeT root){ stack<treeT *> s; pTreeT pre=NULL; while ((NULL != root) || !s.empty()) { if (NULL != root) { s.push(root); root = root->left; } else { root = s.top(); if (root->right!=NULL && pre!=root->right){ root=root->right; } else{ root=pre=s.top(); visit(root); s.pop(); root=NULL; } } }}