用鄰接表儲存有向圖並實現DFS(遞迴+非遞迴)BFS(非遞迴)兩種遍歷
阿新 • • 發佈:2019-02-11
程式碼如下:
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<iostream> using namespace std; #define MAX 20 typedef char Dtype; typedef int mapmax[MAX][MAX]; int visited[MAX]; //-----------鄰接表-------------- typedef char Diantype; //弧的結構體 typedef struct ArcNode{ int adddain;//指向頂點位置的指標 struct ArcNode *nextarc;//指向下一條弧的指標 }ArcNode,*Arc; //點的結構體 typedef struct VNode{ Diantype data;//頂點資訊 ArcNode *firstarc;//指向第一條依附該點的弧的指標 }VNode, AdjList[MAX]; typedef struct{ AdjList toulist; //所有頭節點的表 int dian,hu; //當前頂點數和弧數 }ALG; int locate_dian(ALG H,Diantype a); void Creat_ALG(ALG &H); //-------------棧------------------ typedef struct{ Arc *base; int top; int size; }Stack; int Gettop(Stack S,Arc &e); void Pop(Stack &S,Arc &e); void Push(Stack &S,Arc e); int Isempty(Stack S); void InitStack(Stack &S); //------------佇列---------------------- typedef struct { //佇列 int *base; int front; int rear; int tag; }Sq; void InitSq(Sq &QQ); int Getlen(Sq QQ); int Isempty(Sq QQ); void InSq(Sq &QQ,int e); void OutSq(Sq &QQ,int &e); void GetHead(Sq QQ); //-------------DFS----------------- int first(ALG H,int v);//遞迴 void dfs1_ALG(ALG H,int i); //遞迴深度遍歷 void DFS(ALG H,int v); //---------------bfs------------------ void BFS(ALG H) { memset(visited,0,sizeof(visited)); Sq q; InitSq(q); int u; for(int i=1;i<=H.hu;i++) { if(!visited[i]) { visited[i]=1; cout<<H.toulist[i].data; InSq(q,i); ArcNode *p; while(!Isempty(q)) { OutSq(q,u); if(!visited[u]) { cout<<H.toulist[u].data; visited[u]=1; } if(H.toulist[u].firstarc) { p=H.toulist[u].firstarc; } while(p) { if(!visited[p->adddain]) { cout<<H.toulist[p->adddain].data; visited[p->adddain]=1; InSq(q,p->adddain); } p=p->nextarc; } /*for(int w=FirstAdjVex(G,u);w>= 0;w=NextAdjVex(G,u,w)) //註釋掉之後為有向圖 { if( !visited[w]) { visited[w]=1; cout<<H.toulist[u].data; InSq(q,w); }//if }*/ } } } } int main() { ALG A; Creat_ALG(A); memset(visited,0,sizeof(visited)); //----------DFS 遞迴+非遞迴-------------- /* for(int i=1;i<=A.dian;i++) { if(!visited[i]) dfs1_ALG(A,i);//遞迴 DFS(A,i); //非遞迴 } */ //-----------BFS------------------------- printf("\nBFS結果如下\n"); BFS(A); return 0; } //-------------------dfs fei dugui--------------- void DFS(ALG H,int v) { Stack S;InitStack(S); visited[v]=1; cout<<H.toulist[v].data; ArcNode *p=H.toulist[v].firstarc; while(p || !Isempty(S)) { while(p) { if(visited[p->adddain]) p=p->nextarc; else { cout<<H.toulist[p->adddain].data; visited[p->adddain]=1; Push(S,p); p=H.toulist[p->adddain].firstarc; } } if(!Isempty(S)) { Pop(S,p); p=p->nextarc; } } } //---------------digui DFS---------------- int first(ALG H,int v) { ArcNode *p=H.toulist[v].firstarc; if(!p) return 0; else { while(p->nextarc) { if(!visited[p->adddain]) { return p->adddain; break; } p=p->nextarc; } if(!visited[p->adddain]) return p->adddain; return 0; } } void dfs1_ALG(ALG H,int i) //遞迴深度遍歷 { int w; visited[i]=1; cout<<H.toulist[i].data<<endl; for(w=first(H,i);w>0;w=first(H,i)) { if(!visited[w]) dfs1_ALG(H,w); } } //---------------鄰接表---------------------- int locate_dian(ALG H,Diantype a) { for(int i=1;i<=H.dian;i++) { if(H.toulist[i].data==a) return i; } return 0; } void Creat_ALG(ALG &H) {//根據輸入的有向圖G的頂點數及邊數,建立圖G的鄰接表 printf("請輸入點數和弧數\n"); cin>>H.dian>>H.hu; getchar(); printf("請輸入節點資訊\n"); for(int i=1;i<=H.dian;i++) { cin>>H.toulist[i].data; H.toulist[i].firstarc=NULL; } getchar(); printf("請輸入%d條弧\n",H.hu); for(int k=1;k<=H.hu;k++) { Diantype x,y; int i,j; ArcNode *p,*node; cin>>x>>y; getchar(); i=locate_dian(H,x);j=locate_dian(H,y); //----i->j------- node=new ArcNode; node->adddain=j; node->nextarc=NULL; p=H.toulist[i].firstarc; if(!p) H.toulist[i].firstarc=node; else { while(p->nextarc) p=p->nextarc; p->nextarc=node; } //----j->i-------- /*node=new ArcNode; node->adddain=i; node->nextarc=NULL; p=H.toulist[j].firstarc; if(!p) H.toulist[j].firstarc=node; else { while(p->nextarc) p=p->nextarc; p->nextarc=node; } */ } } //---------------------棧----------------- //初始化 void InitStack(Stack &S) { S.base=(Arc*)malloc(MAX*sizeof(ArcNode)); if(!S.base) return ; S.top=0; S.size=MAX; } //判空操作,返回 1 表示棧為空 int Isempty(Stack S) { if(S.top==0) return 1; return 0; } //入棧操作 void Push(Stack &S,Arc e) { if(S.top>=S.size) { printf("該棧已滿\n"); return ; } S.base[S.top++]=e; } //出棧操作 void Pop(Stack &S,Arc &e) { if (Isempty(S)) return; //棧為空 e = S.base[--S.top]; } //Gettop 取棧頂元素 int Gettop(Stack S,Arc &e){ //若棧不空則用e返回S的棧頂元素 if (S.top == 0) return 0; //棧為空 e = S.base[S.top-1]; return 1; } //----------------佇列---------------- void InitSq(Sq &QQ) { QQ.base=(int*)malloc(MAX * sizeof(int)); //S.base=(BiTree*)malloc(MAX*sizeof(BiTree)); if(!QQ.base) return ; QQ.front=QQ.rear=QQ.tag=0; } int Getlen(Sq QQ) { if(!QQ.tag) //分情況討論tag為 0,長度肯定為 0; return 0; else { if(QQ.rear==QQ.front) return MAX; return (QQ.rear-QQ.front+MAX)%MAX; } } int Isempty(Sq QQ) { if(QQ.front==QQ.rear && QQ.tag==0) return 1; return 0; } void InSq(Sq &QQ,int e) { if (QQ.front == QQ.rear && QQ.tag==1) //tag與隊頭隊尾必須同時滿足 { printf("%d\n",QQ.tag); printf("佇列已滿\n"); return ; } QQ.tag=1; // Q.base=(Type )malloc(MAX * sizeof(Type)); QQ.base[QQ.rear] = e; QQ.rear =(QQ.rear+1)%MAX; } void OutSq(Sq &QQ,int &e) { if(QQ.front == QQ.rear && QQ.tag==0) { printf("佇列已空\n"); return; } e=QQ.base[QQ.front]; QQ.front=(QQ.front+1)%MAX; if(QQ.front == QQ.rear) QQ.tag=0; } void GetHead(Sq QQ,int e) { if(QQ.front == QQ.rear && QQ.tag==0) return; e = QQ.base[QQ.front]; }