1 /*C语言建立有向图的邻接表及其遍历操作*/ 2 #include"stdio.h" 3 #include"stdlib.h" 4 //图的邻接矩阵储存结构 5 typedef char elemtype; 6 #define maxsize 10 7 #define queuesize 100 8 //边结点的类型定义 9 typedef struct edgenode 10 { 11 int adjvex;//存放邻接的点在顶点表的下标,邻接点 12 struct edgenode *next;//指向Vi下一个邻接点的边结点 13 int weight;/*权值*/ 14 }edgenode; 15 //顶点结点类型定义 16 typedef struct vexnode 17 { 18 elemtype data; //存储顶点的名称或其相关信息 19 edgenode *firstedge;//边表头指针 20 }vexnode; 21 //图的邻接表数据类型 22 typedef struct{ 23 vexnode vexlist[maxsize];//顶点表 24 int n,e; 25 }graph; 26 //在图g中查找顶点v,存在顶点数组中的下标,不存在返回-1 27 int locatevex(graph g,elemtype v) 28 { 29 int i; 30 for(i=0;i<g.n;i++) 31 if(g.vexlist[i].data==v)return i; 32 return -1; 33 } 34 //打印图信息 35 void print(graph g) 36 { 37 int i; 38 edgenode *p; 39 printf("图的邻接表表示:"); 40 for(i=0;i<g.n;i++){ 41 printf("\n%4c",g.vexlist[i].data); 42 p=g.vexlist[i].firstedge; 43 while(p!=NULL){ 44 printf("-->%d",p->adjvex);p=p->next; 45 } 46 } 47 printf("\n"); 48 } 49 void creategraph(graph *g){ 50 int i,j,k; 51 elemtype v1,v2; 52 edgenode *s; 53 printf("请输入图的顶点数及边数\n"); 54 printf("顶点数 n=");scanf("%d",&g->n); 55 printf("边 数 e=");scanf("%d",&g->e); 56 printf("请输入图的顶点信息:\n");getchar(); 57 for(i=0;i<=g->n;i++){ 58 scanf("%c",&g->vexlist[i].data); //构造顶点信息 59 g->vexlist[i].firstedge=NULL; 60 } 61 printf("请输入图的边的信息:\n"); 62 for(k=0;k<g->e;k++) 63 { 64 printf("请输入第%d条边的两个端点下标:",k+1); 65 scanf("%c%c",&v1,&v2);getchar();//输入一条边的两个顶点 66 i=locatevex(*g,v1); 67 j=locatevex(*g,v2); 68 if(i>=0&&j>=0){ 69 //建立无向图的邻接表 70 /*s=(edgenode *)malloc(sizeof(edgenode)); 71 s->adjvex=j; 72 s->next=g->vexlist[i].firstedge; 73 g->vexlist[i].firstedge=s; 74 75 s=(edgenode *)malloc(sizeof(edgenode)); 76 s->adjvex=i; 77 s->next=g->vexlist[j].firstedge; 78 g->vexlist[j].firstedge=s;*/ 79 //建立有向图的邻接表 80 s=(edgenode *)malloc(sizeof(edgenode)); 81 s->adjvex=j; 82 s->next=g->vexlist[i].firstedge; 83 g->vexlist[i].firstedge=s; 84 } 85 } 86 } 87 int visited[maxsize];/* 访问标志数组*/ 88 /*从第i个顶点出发递归地深度优先遍历图G*/ 89 void DFS(graph g,int i) 90 { 91 edgenode *p; 92 printf("%3c",g.vexlist[i].data);/*访问第i个项点*/ 93 visited[i]=1; 94 p=g.vexlist[i].firstedge; 95 while(p!=NULL) { 96 if(visited[p->adjvex]==0) 97 DFS(g,p->adjvex);/*对i的尚未访问的邻接顶点j递归调用DFS*/ 98 p=p->next; 99 } 100 } 101 void DFStraverse(graph g) /*对图G进行深度优先遍历*/ 102 { 103 int v; 104 for (v=0; v<g.n;v++)visited[v]=0; /*初始化标志数组*/ 105 for (v=0; v<g.n;v++) /*保证非连通图的遍历*/ 106 /*从第v个顶点出发递归地深度优先遍历图G*/ 107 if (!visited[v])DFS(g,v); 108 } 109 //循环队列存储结构定义 110 typedef struct cirqueue 111 { 112 elemtype *data; //队列存储空间的首地址 113 int front; //队头位置:指向当前队头元素 114 int rear; //队尾位置:指向当前队尾元素的下一位置 115 }cirqueue; // 循环队列 116 //构造空队,如果成功,返回1,如果失败,返回0 117 int initqueue(cirqueue *q) 118 { 119 q->data=(elemtype *)malloc(queuesize*sizeof(cirqueue)); 120 if (q->data==NULL)return 0; // 存储分配失败 121 q->front=q->rear=0; 122 return 1; 123 } 124 // 插入元素e为Q的新的队尾元素 ,如果成功,返回1,如果失败,返回0 125 int enqueue (cirqueue *q,elemtype e) 126 { 127 if ((q->rear+1) % queuesize == q->front) 128 return 0; //队列满 129 q->data[q->rear] = e; 130 q->rear = (q->rear+1) % queuesize; //队尾后移一位 131 return 1; 132 } 133 //若队列不空,则删除Q的队头元素,用e返回其值,并返回1;否则返回0 134 int dequeue (cirqueue *q,int *e) 135 { 136 if (q->front == q->rear) return 0; //队列为空 137 *e = q->data[q->front]; 138 q->front = (q->front+1) %queuesize; //队头后移一位 139 return 1; 140 } 141 //若栈不空,则用e返回队头元素,并返回1;否则返回0 142 int getfront(cirqueue q,elemtype *e) 143 { 144 if (q.front == q.rear) return 0; //队列为空 145 *e=q.data[q.front]; 146 return 1; 147 } 148 //若队列为空栈,则返回1,否则返回0 149 int queueempty(cirqueue q)//栈非空 150 { 151 if(q.front == q.rear)return 1; //队列为空 152 else return 0; 153 } 154 //返回队列的元素个数,即队列的长度 155 int queuelength(cirqueue q) 156 { 157 return (q.rear-q.front+queuesize) % queuesize; 158 } 159 //【算法6-10:利用邻接矩阵实现连通图的广度优先搜索遍历】 160 int BFSvisited[maxsize]; 161 cirqueue q; 162 /*从第k个顶点出发广度优先遍历图G,G以邻接矩阵表示。*/ 163 void BFS(graph g,int k){ 164 int i; 165 edgenode *p; 166 initqueue(&q);/*初始化队列*/ 167 printf("%3c",g.vexlist[k].data);/*访问第k个项点*/ 168 visited[k]=1; 169 enqueue(&q,k);/*第k个顶点进队*/ 170 while(queueempty(q)==0) {/*队列非空*/ 171 dequeue(&q,&i); 172 p=g.vexlist[i].firstedge;/*获取第1个邻接点*/ 173 while(p!=NULL){ 174 if(visited[p->adjvex]==0){ 175 /*访问第i个顶点的末曾访问的顶点*/ 176 printf("%3c",g.vexlist[p->adjvex].data); 177 visited[p->adjvex]=1; 178 enqueue(&q,p->adjvex);/*第k个顶点进队*/ 179 } 180 p=p->next; 181 } 182 } 183 } 184 void BFStraverse(graph g) //对图G进行广度优先遍历 185 { 186 int v; 187 for (v=0; v<g.n;v++) //初始化标志数组 188 visited[v]=0; 189 for (v=0; v<g.n;v++) //保证非连通图的遍历 190 if (!visited[v])BFS(g,v); 191 //从第v个顶点出发递归地深度优先遍历图G 192 } 193 int main() 194 { 195 graph g; 196 creategraph(&g); 197 print(g); 198 printf("\n"); 199 printf("图的深度优先遍历序列:\n"); 200 DFStraverse(g); 201 printf("\n"); 202 printf("图的广度优先遍历序列:\n"); 203 BFStraverse(g); 204 printf("\n"); 205 return 0; 206 }
原文地址:https://www.cnblogs.com/1772642558sgzj/p/9354882.html
时间: 2024-10-13 00:31:23