二叉树的深度优先和广度优先遍历

来源:互联网 发布:网络劫持金山毒霸 编辑:程序博客网 时间:2024/04/29 16:12

图的深度优先搜索法是树的先根遍历的推广

它的基本思想是:从图G的某个顶点v0出发,访问v0,然后选择一个与v0相邻且没被访问过的顶点vi访问,再 从vi出发选择一个与vi相邻且未被访问的顶点vj进行访问,依次继续。如果当前被访问过的顶点的所有邻接顶点都已被访问,则退回到已被访问的顶点序列中 最后一个拥有未被访问的相邻顶点的顶点w,从w出发按同样的方法向前遍历,直到图中所有顶点都被访问。

图的广度优先搜索是树的按层次遍历的推广

它的基本思想是:首先访问初始点vi,并将其标记为已访问过,接着访问vi的所有未被访问过的邻接点 vi1,vi2, …, vi t,并均标记已访问过,然后再按照vi1,vi2, …, vi t的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过,依次类推,直到图中所有和初始点vi有路径相通的顶点都被访问过为止。

二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。

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;}

教科书标准算法及优化算法

先序遍历非递归算法

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 }

中序遍历非递归算法

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}

后序遍历非递归算法

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

前序最简洁非递归算法

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);       }}

后序算法之二

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;                     }              }       }}
0 0
原创粉丝点击