1 #include<stdio.h>
2 #include<stdlib.h>
3
4 #define OK 1
5 #define ERROR 0
6 #define MAX_VERTAX_SIZE 20
7
8 typedef char VerElemType;
9 typedef char ElemType;
10 typedef int Status;
11
12 typedef struct Graph{
13 VerElemType VertaxMatrix[MAX_VERTAX_SIZE]; //顶点数组
14 int AdjacentMatrix[MAX_VERTAX_SIZE][MAX_VERTAX_SIZE]; //邻接矩阵
15 int VertaxNum; //顶点的个数
16 int EageNum; //边的个数
17 }Graph;
18
19 //队列,在图的广度优先遍历中使用
20 typedef struct QueueNode{
21 ElemType data;
22 struct QueueNode* next;
23 }QueueNode, *QueueNodePtr;
24 typedef struct Queue{
25 QueueNodePtr front;
26 QueueNodePtr rear;
27 }Queue;
28
29 Status InitQueue(Queue* q){
30 (*q).front = (QueueNodePtr)malloc(sizeof(struct QueueNode));
31 (*q).rear = (*q).front;
32 (*q).rear->next = NULL;
33 return OK;
34 }
35 Status EnterQueue(Queue* q, ElemType e){
36 QueueNodePtr n;
37 n = (QueueNode*)malloc(sizeof(struct QueueNode));
38 n->data = e;
39 n->next = q->rear->next;
40 q->rear->next = n;
41 q->rear = n;
42 return OK;
43 }
44 Status DeleteQueue(Queue* q, ElemType* e){
45 QueueNodePtr p;
46 if( q->front == q->rear ){
47 printf("Empty\n");
48 return ERROR;
49 }
50 p = q->front->next;
51 *e = p->data;
52 q->front->next = p->next;
53 free(p);
54 if( p == q->rear )
55 q->rear = q->front;
56 return OK;
57 }
58 Status IsQueueEmpty(Queue q){
59 return q.front == q.rear ? OK : ERROR;
60 }
61
62 //定位某个顶点的下标
63 int LocateVertax(Graph G, VerElemType ver){ //测试1通过
64 int i;
65 for( i = 0; i < G.VertaxNum; i++ ){
66 if( G.VertaxMatrix[i] == ver )
67 return i;
68 }
69 return -1;
70 }
71 //创建无向图
72 Status CreateUDG(Graph* G){
73 int i,j,k;
74 VerElemType x,y;
75 printf(" Create Undigraph.\n");
76 printf("Please enter the number of Vertax and Eage: \n");
77 scanf("%d %d%*c",&(*G).VertaxNum, &(G->EageNum)); //%*c吃掉回车
78
79 printf("ok, please input value of %d Vertax.\n", G->VertaxNum );
80 for( i = 0; i < G->VertaxNum; i++ ){ //初始化顶点数组
81 scanf("%c%*c", &(G->VertaxMatrix[i]));
82 }
83
84 for( i = 0; i < G->VertaxNum; i++ ) //初始化邻接表
85 for( j = 0; j < G->VertaxNum; j++ )
86 G->AdjacentMatrix[i][j] = 0;
87 //for( i = 0; i < G->VertaxNum; i++ ){ //初始化邻接表
88 // for( j = 0; j < G->VertaxNum; j++ )
89 // printf("%d ", G->AdjacentMatrix[i][j]);
90 // printf("\n");
91 //}
92
93 for( k = 0; k < G->EageNum; k++ ){
94 printf("ok, please input two Vertax of Eage: %d,separated by Spaces.\n", k+1 );
95 scanf("%c %c%*c", &x, &y);
96 i = LocateVertax(*G, x);
97 j = LocateVertax(*G, y);
98 G->AdjacentMatrix[i][j] = G->AdjacentMatrix[j][i] = 1;
99 }
100 return OK;
101 }
102 //打印邻接矩阵
103 Status PrintAdjacentMatrix(Graph G){
104 int i, j;
105 printf(" Adjacent Matrix\n");
106 for( i = 0; i < G.VertaxNum; i++ ){
107 for( j = 0; j < G.VertaxNum; j++){
108 printf("%3d", G.AdjacentMatrix[i][j]);
109 }
110 printf("\n");
111 }
112 return OK;
113 }
114
115 //图的深度优先遍历
116 //返回v的第一个邻接顶点,若没有邻接顶点,返回-1
117 int FirstAdjacentVertax(Graph G, VerElemType v){
118 int index_v = LocateVertax(G, v);
119 int i;
120 for( i = 0; i < G.VertaxNum; i++ ){
121 if( G.AdjacentMatrix[index_v][i] == 1)
122 return i;
123 }
124 return -1;
125 }
126 //w是v的邻接点,返回v的除了w(从w开始)的下一个邻接顶点,没有则返回-1
127 int NextAdjacentVertax(Graph G, VerElemType v, VerElemType w){
128 int index_v = LocateVertax(G, v);
129 int index_w = LocateVertax(G, w);
130 int i;
131 for( i = index_w + 1; i < G.VertaxNum; i++ ){
132 if( G.AdjacentMatrix[index_v][i] == 1 )
133 return i;
134 }
135 return -1;
136 }
137 //DFS的递归思想: 访问v,
138 // 从v的第一邻接点开始深度优先遍历,
139 // 然后从v的第二邻接开始深度优先遍历。直到没有邻接点
140
141 int visitedArray[MAX_VERTAX_SIZE];
142
143 void visit(VerElemType c){
144 printf("%c ", c);
145 }
146 VerElemType GetVertaxValue(Graph G, int position){
147 return G.VertaxMatrix[position];
148 }
149 Status DFS(Graph G, VerElemType v){ //Depth First Search
150 VerElemType w;
151 visit(v);
152 visitedArray[LocateVertax(G, v)] = 1; //已访问,1
153
154 for(w = GetVertaxValue(G, FirstAdjacentVertax(G, v)); LocateVertax(G, w) != -1; w = GetVertaxValue(G, NextAdjacentVertax(G, v, w))){
155 if( visitedArray[LocateVertax(G, w)] != 1 )
156 DFS(G, w);
157 }
158 return OK;
159 }
160 Status DFSTraverse(Graph G){
161 int i;
162 for( i = 0; i < G.VertaxNum; i++ ){
163 visitedArray[i] = 0;
164 }
165 for( i = 0; i < G.VertaxNum; i++){
166 if( visitedArray[i] == 0 ){
167 DFS(G, GetVertaxValue(G, i));
168 }
169 }
170 return OK;
171 }
172 //BFS(广度优先遍历):利用队列和树的层次遍历相似
173 //思想: 将第一个顶点入队,
174 // 将对中的元素出队,如果没有访问过,则调用visit访问,将其所有的邻接顶点入队
175 Status BFSTraverse(Graph G){
176 ElemType c;
177 Queue q;
178 InitQueue(&q);
179 int i,j;
180 for( i = 0; i < G.VertaxNum; i++ )
181 visitedArray[i] = 0;
182
183 for( i = 0; i < G.VertaxNum; i++ ){
184 if( visitedArray[i] == 0 ){
185 EnterQueue(&q, G.VertaxMatrix[i]);
186 visitedArray[i] = 1;
187 while( IsQueueEmpty(q) != OK ){
188 DeleteQueue(&q, &c); //进到队里的都是编辑为访问过,这样队里不会有重复的点进来
189 visit(c);
190 for( j = FirstAdjacentVertax(G, c); j != -1; j = NextAdjacentVertax(G, c, GetVertaxValue(G, j))){
191 if( visitedArray[j] == 0 ){
192 EnterQueue(&q, GetVertaxValue(G, j));
193 visitedArray[j] = 1; //进到队里的都是编辑为访问过,这样队里不会有重复的点进来
194 }
195 }
196 }
197 }
198 }
199
200 }
201
202 int main(){
203 Graph G;
204 CreateUDG(&G);
205 PrintAdjacentMatrix(G);
206 printf("the Result of DFS(Depth First Search) is: ");
207 DFSTraverse(G);
208 printf("\nthe REsult of BFS(Breadth First Srarch) is: ");
209 BFSTraverse(G);
210 return 0;
211 }