二叉樹的廣度遍歷和深度遍歷()

love_gg發表於2012-09-12
圖的深度優先搜尋法是樹的先根遍歷的推廣,它的基本思想是:從圖G的某個頂點v0出發,訪問v0,然後選擇一個與v0相鄰且沒被訪問過的頂點vi訪問,再從vi出發選擇一個與vi相鄰且未被訪問的頂點vj進行訪問,依次繼續。如果當前被訪問過的頂點的所有鄰接頂點都已被訪問,則退回到已被訪問的頂點序列中最後一個擁有未被訪問的相鄰頂點的頂點w,從w出發按同樣的方法向前遍歷,直到圖中所有頂點都被訪問。

圖的廣度優先搜尋是樹的按層次遍歷的推廣,它的基本思想是:首先訪問初始點vi,並將其標記為已訪問過,接著訪問vi的所有未被訪問過的鄰接點vi1,vi2, …, vi t,並均標記已訪問過,然後再按照vi1,vi2, …, vi t的次序,訪問每一個頂點的所有未被訪問過的鄰接點,並均標記為已訪問過,依次類推,直到圖中所有和初始點vi有路徑相通的頂點都被訪問過為止。

二叉樹的深度優先遍歷的非遞迴的通用做法是採用棧,廣度優先遍歷的非遞迴的通用做法是採用佇列。

  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3. #include <math.h>  
  4.   
  5. /* 函式結果狀態程式碼 */  
  6. #define TRUE 1  
  7. #define FALSE 0  
  8. #define OK 1  
  9. #define ERROR 0  
  10. #define INFEASIBLE -1  
  11. #define OVERFLOW  3  
  12. #define MAXSIZE 100 /* 儲存空間初始分配量 */  
  13.   
  14. typedef int Status; /* Status是函式的型別,其值是函式結果狀態程式碼,如OK等 */  
  15. typedef char ElemType;   
  16.   
  17. typedef struct BiTNode {  
  18.     ElemType data;  
  19.     struct BiTNode *lchild, *rchild; /* 左右孩子指標 */  
  20. } BiTNode, *BiTree;  
  21.   
  22. /* 鏈棧結構 */  
  23. typedef struct StackNode  
  24. {  
  25.     BiTNode data;  
  26.     struct StackNode *next;  
  27. }StackNode,*LinkStackPtr;  
  28.   
  29. typedef struct  
  30. {  
  31.     LinkStackPtr top;  
  32.     int count;  
  33. }LinkStack;  
  34.   
  35. /*佇列結構*/  
  36. typedef struct QNode {  
  37.     BiTNode data;  
  38.     struct QNode *next;  
  39. } QNode, *QueuePtr;  
  40.   
  41. typedef struct {  
  42.     QueuePtr front, rear; /* 隊頭、隊尾指標 */  
  43. } LinkQueue;  
  44.   
  45. /* 鏈佇列 的基本操作*/  
  46. void InitQueue(LinkQueue *Q)  
  47. {  
  48.     /* 構造一個空佇列Q */  
  49.     (*Q).front = (*Q).rear = (QueuePtr)malloc(100*sizeof(QNode));  
  50.     if(!(*Q).front)  
  51.         exit(OVERFLOW);  
  52.     (*Q).front->next = NULL;  
  53. }  
  54. void DestroyQueue(LinkQueue *Q)  
  55. {  
  56.     /* 銷燬佇列Q(無論空否均可) */  
  57.     while((*Q).front) {  
  58.         (*Q).rear = (*Q).front->next;  
  59.         free((*Q).front);  
  60.         (*Q).front = (*Q).rear;  
  61.     }  
  62. }  
  63. Status QueueEmpty(LinkQueue Q)  
  64. {  
  65.     /* 若Q為空佇列,則返回TRUE,否則返回FALSE */  
  66.     if(Q.front->next == NULL)  
  67.         return TRUE;  
  68.     else  
  69.         return FALSE;  
  70. }  
  71. Status GetHead_Q(LinkQueue Q, BiTNode *e) /* 避免與bo2-6.c重名 */  
  72. {  
  73.     /* 若佇列不空,則用e返回Q的隊頭元素,並返回OK,否則返回ERROR */  
  74.     QueuePtr p;  
  75.     if(Q.front == Q.rear)  
  76.         return ERROR;  
  77.     p = Q.front->next;  
  78.     *e = p->data;  
  79.     return OK;  
  80. }  
  81. void EnQueue(LinkQueue *Q, BiTNode e)  
  82. {  
  83.     /* 插入元素e為Q的新的隊尾元素 */  
  84.     QueuePtr p = (QueuePtr)malloc(sizeof(QNode));  
  85.     if(!p) /* 儲存分配失敗 */  
  86.         exit(OVERFLOW);  
  87.     p->data =e;  
  88.     p->next = NULL;  
  89.     (*Q).rear->next = p;  
  90.     (*Q).rear = p;  
  91. }  
  92. Status DeQueue(LinkQueue *Q, BiTNode *e)  
  93. {  
  94.     /* 若佇列不空,刪除Q的隊頭元素,用e返回其值,並返回OK,否則返回ERROR */  
  95.     QueuePtr p;  
  96.     if((*Q).front == (*Q).rear)  
  97.         return ERROR;  
  98.     p = (*Q).front->next;  
  99.     *e = p->data;  
  100.     (*Q).front->next = p->next;  
  101.     if((*Q).rear == p)  
  102.         (*Q).rear = (*Q).front;  
  103.     free(p);  
  104.     return OK;  
  105. }  
  106. //#####################################################//  
  107.   
  108. /* 鏈棧的基本操作*/  
  109. /*  構造一個空棧S */  
  110. Status InitStack(LinkStack *S)  
  111. {   
  112.     S->top = (LinkStackPtr)malloc(sizeof(StackNode));  
  113.     if(!S->top)  
  114.             return ERROR;  
  115.     S->top=NULL;  
  116.     S->count=0;  
  117.     return OK;  
  118. }  
  119.   
  120. /* 把S置為空棧 */  
  121. Status ClearStack(LinkStack *S)  
  122. {   
  123.     LinkStackPtr p,q;  
  124.     p=S->top;  
  125.     while(p)  
  126.     {    
  127.         q=p;  
  128.         p=p->next;  
  129.         free(q);  
  130.     }   
  131.     S->count=0;  
  132.     return OK;  
  133. }  
  134.   
  135. /* 若棧S為空棧,則返回TRUE,否則返回FALSE */  
  136. Status StackEmpty(LinkStack S)  
  137. {   
  138.     if (S.count==0)  
  139.         return TRUE;  
  140.     else  
  141.         return FALSE;  
  142. }  
  143.   
  144. /* 返回S的元素個數,即棧的長度 */  
  145. int StackLength(LinkStack S)  
  146. {   
  147.     return S.count;  
  148. }  
  149.   
  150. /* 若棧不空,則用e返回S的棧頂元素,並返回OK;否則返回ERROR */  
  151. Status GetTop(LinkStack S, BiTNode *e)  
  152. {  
  153.     if (S.top==NULL)  
  154.         return ERROR;  
  155.     else  
  156.         *e=S.top->data;  
  157.     return OK;  
  158. }  
  159.   
  160. /* 插入元素e為新的棧頂元素 */  
  161. Status Push(LinkStack *S, BiTNode e)  
  162. {  
  163.     LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode));   
  164.     s->data=e;   
  165.     s->next=S->top;   /* 把當前的棧頂元素賦值給新結點的直接後繼*/  
  166.     S->top=s;         /* 將新的結點s賦值給棧頂指標*/  
  167.     S->count++;  
  168.     return OK;  
  169. }  
  170.   
  171. /* 若棧不空,則刪除S的棧頂元素,用e返回其值,並返回OK;否則返回ERROR */  
  172. Status Pop(LinkStack *S, BiTNode *e)  
  173. {   
  174.     LinkStackPtr p;  
  175.     if(StackEmpty(*S))  
  176.         return ERROR;  
  177.     *e=S->top->data;  
  178.     p=S->top;                /* 將棧頂結點賦值給p */  
  179.     S->top=S->top->next;    /* 使得棧頂指標下移一位,指向後一結點*/  
  180.     free(p);                /* 釋放結點p */          
  181.     S->count--;  
  182.     return OK;  
  183. }  
  184.   
  185. /* 用於構造二叉樹********************************** */  
  186. int count=1;  
  187. typedef char String[100]; /*  0號單元存放串的長度 */  
  188. String str;  
  189.   
  190. Status StrAssign(String T,char *chars)  
  191. {   
  192.     int i;  
  193.     if(strlen(chars)>MAXSIZE)  
  194.         return ERROR;  
  195.     else  
  196.     {  
  197.         T[0]=strlen(chars);  
  198.         for(i=1;i<=T[0];i++)  
  199.             T[i]=*(chars+i-1);  
  200.         return OK;  
  201.     }  
  202. }  
  203. /* ************************************************ */  
  204.   
  205. void CreateBiTree(BiTree *T)  
  206. {  
  207.     /* 按先序次序輸入二叉樹中結點的值(此處字元型)*/  
  208.     /* 構造二叉連結串列表示的二叉樹T。 */  
  209.     ElemType ch;  
  210.     ch=str[count++];  
  211.     if(ch == '#'/* 空 */  
  212.         *T = NULL;  
  213.     else {  
  214.         *T = (BiTree)malloc(sizeof(BiTNode)); /* 生成根結點 */  
  215.         if(!*T)  
  216.             exit(OVERFLOW);  
  217.         (*T)->data = ch;  
  218.         CreateBiTree(&(*T)->lchild); /* 構造左子樹 */  
  219.         CreateBiTree(&(*T)->rchild); /* 構造右子樹 */  
  220.     }  
  221. }  
  222.   
  223. void InitBiTree(BiTree *T)  
  224. {  
  225.     /* 操作結果:構造空二叉樹T */  
  226.     *T = NULL;  
  227. }  
  228.   
  229. void DestroyBiTree(BiTree *T)  
  230. {  
  231.     /* 初始條件:二叉樹T存在。操作結果:銷燬二叉樹T */  
  232.     if(*T) { /* 非空樹 */  
  233.         if((*T)->lchild) /* 有左孩子 */  
  234.             DestroyBiTree(&(*T)->lchild); /* 銷燬左孩子子樹 */  
  235.         if((*T)->rchild) /* 有右孩子 */  
  236.             DestroyBiTree(&(*T)->rchild); /* 銷燬右孩子子樹 */  
  237.         free(*T); /* 釋放根結點 */  
  238.         *T = NULL; /* 空指標賦0 */  
  239.     }  
  240. }  
  241.   
  242. /*廣度優先遍歷,層序*/  
  243. void BFSTree(BiTree T)  
  244. {  
  245.     LinkQueue Q;  
  246.     BiTNode e;  
  247.     InitQueue(&Q);  
  248.     EnQueue(&Q,*T);  
  249.     printf("BFSTree: ");  
  250.     while(!QueueEmpty( Q)){  
  251.         DeQueue(&Q, &e);  
  252.         printf("%c",e.data);  
  253.         if(T->lchild != NULL)  
  254.         {  
  255.             EnQueue(&Q, *(T->lchild));  
  256.         }  
  257.         if(T->rchild != NULL)  
  258.         {  
  259.             EnQueue(&Q, *(T->rchild));  
  260.         }  
  261.         GetHead_Q(Q,  &e);  
  262.         T = &e;       
  263.     }  
  264.     printf("\n");  
  265.     DestroyQueue(&Q);  
  266. }  
  267.   
  268. /*深度優先遍歷,前序*/  
  269. void DFSTree(BiTree T)  
  270. {  
  271.     LinkStack S;  
  272.     BiTNode e;  
  273.     InitStack(&S);  
  274.     Push(&S, *T);  
  275.     printf("DFSTree: ");  
  276.     while(!StackEmpty(S)){  
  277.         Pop(&S, &e);  
  278.         printf("%c",e.data);  
  279.         if(T->rchild != NULL)  
  280.         {  
  281.             Push(&S, *(T->rchild));  
  282.         }  
  283.         if(T->lchild != NULL)  
  284.         {  
  285.             Push(&S, *(T->lchild));  
  286.         }     
  287.         GetTop(S, &e);  
  288.         T = &e;   
  289.     }  
  290.     printf("\n");  
  291.     ClearStack(&S);  
  292. }  
  293.   
  294.   
  295. int main(void)  
  296. {  
  297.     BiTree t;  
  298.   
  299.     InitBiTree(&t);  
  300.     StrAssign(str,"abd##e##cf##g##");  
  301.   
  302.     CreateBiTree(&t);  
  303.     BFSTree(t);  
  304.     DFSTree(t);  
  305.     DestroyBiTree(&t);  
  306. }  



。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

#include"iostream.h"
template <class T>
struct BiNode
{
 T data;
 BiNode<T>*lchild, * rchild;
};
template <class T>
class BiTree
{
 private:
  BiNode <T>*root;
  void creat(BiNode<T>*&r);
  void Release(BiNode<T>*r);
  void Preorder(BiNode<T>*r);
  void Inorder(BiNode<T>*r);
  void Postorder(BiNode<T>*r);
  void Levelorder(BiNode<T>*r);
 public:
  BiTree()
  {
   root=NULL;creat(root);
  }
  ~BiTree()
  {
   Release(root);
  }
  void Pre()
  {
   Preorder(root);
  }
  void In()
  {
   Inorder(root);
  }
  void Post()
  {
   Postorder(root);
  }
  void Level()
  {
   Levelorder(root);
  }
};
template<class T>
void BiTree<T>::Levelorder (BiNode<T>*r)//層序遍歷
{
 BiNode<T>*Q[100];
 int front,rear;
    BiNode<T>* q;
 front=rear=0;
 if(r==NULL)return;
 Q[++rear]=r;
 while(front!=rear)
 {
  q=Q[++front];
  cout<<q->data;
  if(q->lchild!=NULL)
   Q[++rear]=q->lchild;
  if(q->rchild!=NULL)
   Q[++rear]=q->rchild;
 }
}
template<class T>
void BiTree<T>::Preorder (BiNode<T>*r)//前序遍歷
{
 if(r==NULL) return;
 else
 {
  cout<<r->data;
  Preorder(r->lchild);
  Preorder(r->rchild);
 }
}
template<class T>
void BiTree<T>::Postorder (BiNode<T>*r)//後序遍歷
{
 if(r==NULL) return;
 else
 {
  Postorder(r->lchild);
  Postorder(r->rchild);
  cout<<r->data;
 }
}
template<class T>
void BiTree<T>::Inorder (BiNode<T>*r)//中序遍歷
{
 if(r==NULL) return;
 else
 {
  Inorder(r->lchild);
  cout<<r->data;
     Inorder(r->rchild);
 }
}
template<class T>
void BiTree<T>::creat (BiNode<T> *&r)
{
 char ch;
 cin>>ch;
 if(ch=='#')r=NULL;//#表示空節點
 else
 {
  r=new BiNode<T>;
  r->data=ch;
  creat(r->lchild);
  creat(r->rchild);
 }
}
template<class T>
void BiTree<T>::Release (BiNode<T>*r)
{
 if(r!=NULL)
 {
  Release(r->lchild);
     Release(r->rchild);
     delete r;
 }
}
void main()
{
 BiTree<char> au;
   cout<<"輸出後序遍歷:"<<endl;
   au.Post ();
   cout<<endl;
   cout<<"輸出中序遍歷:"<<endl;
   au.In ();
   cout<<endl;
   cout<<"輸出層序遍歷:"<<endl;
   au.Level ();
   cout<<endl;
   cout<<"輸出前序遍歷:"<<endl;
   au.Pre ();
   cout<<endl;
}
。。。。。。。。。。。。。。。。。

#include <iostream>
  using namespace std;
 typedef struct node {
         char data;
         struct node *lchild;
         struct node *rchild;
         }BiNode,*BiTree;
 typedef struct node1{
         BiTree data[30];     //預設30個元素 ,這裡需要一個輔助堆疊!!!
         int top;
         }Stack;
         
 void createTree(BiTree &T)   //先序遞迴建立樹,這裡注意引數的型別,T的型別是 "*&" ,如果是 "**" 程式碼稍加改動就OK...
 {
      char ch;
      cin.get(ch).get();      //過濾輸入流中每次回車產生的回車符
      if (ch==' ') T=NULL;    //這裡首先判斷是不是空格,如果是,則為該節點賦NULL
      else{
             T=(BiTree)malloc(sizeof(BiNode));
             T->data=ch;
             createTree(T->lchild);
             createTree(T->rchild);
           }
 }
 void initstack(Stack *&st)
 {
      st=(Stack *)malloc(sizeof(Stack));
      st->top=-1;
 }
 bool isempty(Stack *st)
 {
     return st->top==-1;
 }
 bool isfull(Stack *st)
 {
     return st->top==19;
 }
 void push(Stack *st,BiTree T)
 {
      if (!isfull(st))
      st->data[++st->top]=T;     //棧頂指標始終指向堆疊最上面可用的一個元素,因此入棧時候,先要將指標加1,然後再執行入棧操作!
      else cout<<"已滿"<<endl;
 }
 BiTree pop(Stack *st)
 {
      if (!isempty(st)) return st->data[st->top--];
 }
 BiTree gettop(Stack *st)
 {
        if (!isempty(st)) return st->data[st->top];  //出棧時,先取出棧頂指標指向的元素,然後再將指標減1,使其指向棧中下一個可用元素!
 }
 void preOrderNoRe(BiTree T)          // 前序遍歷
 {
    Stack *st;
    initstack(st);
    BiTree p;
    p=T;
      while (p!=NULL||!isempty(st))
      {
            while (p!=NULL)
            {
                  cout<<p->data<<"  ";
                  push(st,p);
                  p=p->lchild;
            }
            if (!isempty(st))
            {
                        p=pop(st);
                        p=p->rchild;
            }
            
      }
 }
 void inOrderNoRe(BiTree T)       //中序遍歷
 {
    Stack *st;
    initstack(st);
    BiTree p;
    p=T;
      while (p!=NULL||!isempty(st))
      {
            while (p!=NULL)
            {
                  push(st,p);
                  p=p->lchild;
            }
            if (!isempty(st))
            {
                        p=pop(st);
                        cout<<p->data<<"  ";
                        p=p->rchild;
            }
            
      }
 }
 void postOrderNoRe(BiTree T)          //後序遍歷
 {
      BiTree p;
      Stack *st;
      initstack(st);
      p=T;
      int Tag[20];      //棧,用於標識從左(0)或右(1)返回 
      while (p!=NULL || !isempty(st))
      {
            while (p!=NULL)
            {
                  push(st,p);
                  Tag[st->top]=0;
                  p=p->lchild;
            }
            while (!isempty(st)&&Tag[st->top]==1)
            {
                  p=pop(st);
                  cout<<p->data<<"  ";
            }
            if (!isempty(st))
            {
                             Tag[st->top]=1;   //設定標記右子樹已經訪問 
                             p=gettop(st);
                             p=p->rchild;
            }
            else break;
      }
 }
 int main()
 {
     cout<<"Enter char one by one                      hicjiajia"<<endl;
     BiNode *T;
     createTree(T);
     cout<<endl;
     
     cout<<"preOrderNoRe:  ";preOrderNoRe(T);cout<<endl;
     cout<<"inOrderNoRe:   ";inOrderNoRe(T);cout<<endl;
     cout<<"postOrderNoRe: ";postOrderNoRe(T);cout<<endl; 
     system("pause");
     return 0;
 }

相關文章