1 /*C語言建立有向圖的鄰接矩陣及其遍歷操作*/ 2 #include"stdio.h" 3 #include"stdlib.h" 4 //圖的鄰接矩陣儲存結構 5 typedef char elemtype; 6 #define maxsize 10 7 #define queuesize 100 8 typedef struct{ 9 elemtype vex[maxsize];//頂點表 10 int arc[maxsize][maxsize];//鄰接矩陣 11 int n,e;//邊數,頂點數 12 }graph; 13 //在圖中查找頂點v,存在返回其在頂點數組中的下標,不存在返回-1 14 int locatevex(graph g,elemtype v) 15 { 16 int i; 17 for(i=0;i<g.n;i++)if(g.vex[i]==v)return i; 18 return -1; 19 } 20 //打印信息 21 void print(graph g) 22 { 23 int i,j; 24 printf("圖的鄰接矩陣表示:\n"); 25 for(i=0;i<g.n;i++){ 26 for(j=0;j<g.n;j++){ 27 printf("%3d",g.arc[i][j]); 28 } 29 printf("\n"); 30 } 31 } 32 //創建有向圖的鄰接矩陣 33 void creategraph(graph *g){ 34 int i,j,k; 35 elemtype v1,v2; 36 printf("請輸入頂點數和邊數:\n"); 37 printf("頂點數n=");scanf("%d",&g->n); 38 printf("邊 數e=");scanf("%d",&g->e); 39 printf("請輸入圖的頂點信息:\n"); 40 getchar(); 41 for(i=0;i<=g->n;i++) 42 scanf("%c",&g->vex[i]); 43 for(i=0;i<g->n;i++) 44 for(j=0;j<g->n;j++) 45 g->arc[i][j]=0;//初始化鄰接矩陣 46 printf("請輸入圖的邊的信息:\n"); 47 for(k=0;k<g->e;k++) 48 { 49 printf("請輸入第%d條邊的兩個端點:",k+1); 50 scanf("%c%c",&v1,&v2); 51 fflush(stdin);//清空輸入緩沖區 52 i=locatevex(*g,v1);j=locatevex(*g,v2); 53 if(i>=0&&j>=0){ 54 g->arc[i][j]=1; 55 g->arc[j][i]=1;//無向網矩陣對稱 56 } 57 } 58 } 59 int DFSvisited[maxsize];/* 訪問標志數組*/ 60 /*從第i個頂點出發遞歸地深度優先遍歷圖G*/ 61 void DFS(graph g,int i) 62 { 63 int j; 64 printf("%3c",g.vex[i]); /*訪問第i個項點*/ 65 DFSvisited[i]=1; 66 for(j=0;j<g.n;j++) 67 { 68 if((g.arc[i][j]==1)&&(DFSvisited[j]==0)) 69 DFS(g,j);/* //對i的尚未訪問的鄰接頂點j遞歸調用DFS */ 70 } 71 } 72 //對圖g進行深度優先遍歷 73 void DFStraverse(graph g) 74 { 75 int v; 76 for (v=0; v<g.n;v++)DFSvisited[v]=0; /*初始化標志數組*/ 77 for (v=0; v<g.n;v++) /*保證非連通圖的遍歷,連通圖只執行一次*/ 78 /*從第v個頂點出發遞歸地深度優先遍歷圖G*/ 79 if (!DFSvisited[v]) DFS(g,v); 80 } 81 //循環隊列存儲結構定義 82 typedef struct cirqueue 83 { 84 elemtype *data; //隊列存儲空間的首地址 85 int front; //隊頭位置:指向當前隊頭元素 86 int rear; //隊尾位置:指向當前隊尾元素的下一位置 87 }cirqueue; // 循環隊列 88 //構造空隊,如果成功,返回1,如果失敗,返回0 89 int initqueue(cirqueue *q) 90 { 91 q->data=(elemtype *)malloc(queuesize*sizeof(cirqueue)); 92 if (q->data==NULL)return 0; // 存儲分配失敗 93 q->front=q->rear=0; 94 return 1; 95 } 96 // 插入元素e為Q的新的隊尾元素 ,如果成功,返回1,如果失敗,返回0 97 int enqueue (cirqueue *q,elemtype e) 98 { 99 if ((q->rear+1) % queuesize == q->front) 100 return 0; //隊列滿 101 q->data[q->rear] = e; 102 q->rear = (q->rear+1) % queuesize; //隊尾后移一位 103 return 1; 104 } 105 //若隊列不空,則刪除Q的隊頭元素,用e返回其值,並返回1;否則返回0 106 int dequeue (cirqueue *q,int *e) 107 { 108 if (q->front == q->rear) return 0; //隊列為空 109 *e = q->data[q->front]; 110 q->front = (q->front+1) %queuesize; //隊頭后移一位 111 return 1; 112 } 113 //若棧不空,則用e返回隊頭元素,並返回1;否則返回0 114 int getfront(cirqueue q,elemtype *e) 115 { 116 if (q.front == q.rear) return 0; //隊列為空 117 *e=q.data[q.front]; 118 return 1; 119 } 120 //若隊列為空棧,則返回1,否則返回0 121 int queueempty(cirqueue q)//棧非空 122 { 123 if(q.front == q.rear)return 1; //隊列為空 124 else return 0; 125 } 126 //返回隊列的元素個數,即隊列的長度 127 int queuelength(cirqueue q) 128 { 129 return (q.rear-q.front+queuesize) % queuesize; 130 } 131 //【算法6-10:利用鄰接矩陣實現連通圖的廣度優先搜索遍歷】 132 int BFSvisited[maxsize]; 133 cirqueue q; 134 /*從第k個頂點出發廣度優先遍歷圖G,G以鄰接矩陣表示。*/ 135 void BFS(graph g,int i){ 136 int j; 137 initqueue(&q);/*初始化隊列*/ 138 printf("%3c",g.vex[i]);/*訪問第k個頂點*/ 139 BFSvisited[i]=1; 140 enqueue(&q,i);/*第k個頂點進隊*/ 141 while(queueempty(q)==0) {/*隊列非空*/ 142 dequeue(&q,&i); 143 for(j=0;j<g.n;j++){ 144 if((g.arc[i][j]==1)&&(BFSvisited[j]==0)){ 145 /*訪問第i個頂點的末曾訪問的頂點j*/ 146 printf("%3c",g.vex[j]); 147 BFSvisited[j]=1; 148 enqueue(&q,j);/*第k個頂點進隊*/ 149 } 150 } 151 } 152 } 153 //【算法6-11:對圖G進行廣度優先遍歷】 154 void BFStraverse(graph g) //對圖G進行廣度優先遍歷 155 { 156 int v; 157 for (v=0; v<g.n;v++) //初始化標志數組 158 BFSvisited[v]=0; 159 for (v=0; v<g.n;v++) //保證非連通圖的遍歷 160 if (!BFSvisited[v])BFS(g,v); 161 //從第v個頂點出發遞歸地廣度優先遍歷圖G 162 } 163 int main() 164 { 165 graph g; 166 creategraph(&g); 167 print(g); 168 printf("\n"); 169 printf("圖的深度優先遍歷序列:\n"); 170 DFStraverse(g); 171 printf("\n"); 172 printf("圖的廣度優先遍歷序列:\n"); 173 BFStraverse(g); 174 printf("\n"); 175 return 0; 176 }