图的创建与遍历

图是非线性结构,有两种存储结构,一种是邻接矩阵,另一种是邻接表。

邻接矩阵用一个二维数组来表示。

代码如下:

 1 #include<stdio.h> 
 2 #include<stdlib.h>
 3 #define max_len 100
 4 
 5 typedef struct node{
 6     int num;                    //下标 
 7     int data;                    //数据 
 8 }Point;                            //节点类型 
 9 
10 typedef struct{
11     int pointNum;                //顶点数 
12     int edgeNum;                //边数 
13     Point pointArray[max_len];                //用数组来存放顶点 
14     int edgeArray[max_len][max_len];        //用数组来存放边 
15 }AdjMatrix;                        //矩阵类型 
16 
17 AdjMatrix *create_AdjMatrix(){
18     
19     AdjMatrix *adjMatrix = (AdjMatrix *)malloc(sizeof(AdjMatrix));
20     
21     int i,j,n;
22     printf("输入顶点数:");
23     scanf("%d",&i);
24     printf("输入边数:");
25     scanf("%d",&j);
26     
27     adjMatrix->pointNum = i;
28     adjMatrix->edgeNum = j;
29     
30     for(i=0;i<adjMatrix->pointNum;i++){
31         adjMatrix->pointArray[i].data = i;
32         adjMatrix->pointArray[i].num = i;
33     }
34     
35     for(i=0;i<adjMatrix->pointNum;i++)
36         for(j=0;j<adjMatrix->pointNum;j++)
37             adjMatrix->edgeArray[i][j] = 0;
38     
39     printf("输入边的信息:");
40     for(i=0;i<adjMatrix->edgeNum;i++){
41         scanf("%d %d",&j,&n);
42         adjMatrix->edgeArray[j][n] = 1;
43     }
44     
45     return adjMatrix;
46 }
47 
48 void display(AdjMatrix *adjMatrix){
49     
50     printf("\n");
51     
52     int i,j;
53     for(i=0;i<adjMatrix->pointNum;i++){
54         for(j=0;j<adjMatrix->pointNum;j++)
55             printf("%d ",adjMatrix->edgeArray[i][j]);
56         printf("\n");
57     }
58     
59 }
60 
61 void main(){
62     
63     AdjMatrix *adjMatrix = create_AdjMatrix();
64     display(adjMatrix);
65     
66 }

 

邻接表用链表数组来表示,即链表数组中的每一个元素都是一个链表的头结点,然后这个头结点后面就会跟着一串的链节点,用来表示头结点代表的图中元素可以直接到达链节点代表的图中元素。

代码如下:

 1 #include<stdio.h> 
 2 #include<stdlib.h>
 3 #define max_len 100
 4 
 5 typedef struct node{
 6     int adjvex;
 7     int data;
 8     struct node *nextarc;
 9 }ARCnode;                            //节点类型 
10 
11 typedef struct{
12     int vexdata;
13     ARCnode *firstarc;
14 }VEXnode;                            //头结点类型 
15 
16 typedef struct{
17     int pointNum;                    //顶点数 
18     int edgeNum;                    //边数 
19     VEXnode vexnode[max_len];        //头结点数组 
20 }ALGraph;                            //邻接表类型 
21 
22 
23 ALGraph *create_ALGraph(){
24     
25     ALGraph *algraph = (ALGraph *)malloc(sizeof(ALGraph));
26     ARCnode *arcnode;
27     
28     int i,j,n;
29     printf("输入顶点数:");
30     scanf("%d",&i);
31     printf("输入边数:");
32     scanf("%d",&j);
33     
34     algraph->pointNum = i;
35     algraph->edgeNum = j;
36 
37     
38     for(i=0;i<algraph->edgeNum;i++){
39         algraph->vexnode[i].vexdata = i;
40         algraph->vexnode[i].firstarc = NULL;
41     }
42     
43     printf("输入边的信息:");
44     for(i=0;i<algraph->edgeNum;i++){
45         scanf("%d %d",&j,&n);
46         arcnode = (ARCnode *)malloc(sizeof(ARCnode));
47         arcnode->adjvex = n;
48         arcnode->data = n;
49         arcnode->nextarc = algraph->vexnode[j].firstarc;
50         algraph->vexnode[j].firstarc = arcnode;
51     }
52     
53     return algraph;
54 }
55 
56 void display(ALGraph *algraph){
57     
58     ARCnode *arcnode;
59     
60     int i;
61     for(i=0;i<algraph->edgeNum;i++){
62         printf("%d ",algraph->vexnode[i].vexdata);
63         arcnode = algraph->vexnode[i].firstarc;
64         while(arcnode!=NULL){
65             printf("%d ",arcnode->adjvex);
66             arcnode = arcnode->nextarc;
67         }
68         printf("\n");
69     }
70     
71 }
72 
73 void main(){
74     
75     ALGraph *algraph = create_ALGraph();
76     display(algraph);
77     
78 }

 

深度优先遍历

算法:首先访问某个顶点V1,然后访问与v1邻接的顶点V2,再访问与v2邻接的顶点V3,然后不断重复,直到邻接的顶点vi被访问过,然后退回到Vi-1,访问Vi-1没被访问过的邻接点,再不断重复这两个过程即可访问完所有节点

代码如下:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #define max_len 100
  4 int visited[max_len];
  5 
  6 typedef struct node{
  7     int adjvex;
  8     struct node *nextarc;
  9     int info;
 10 }ARCnode; 
 11 
 12 
 13 typedef struct vexnode{
 14     int vexdata;
 15     ARCnode *firstarc;
 16 }VEXnode;
 17 
 18 typedef struct{
 19     VEXnode vexnode[max_len];
 20     int vexnum,arcnum;
 21 }ALGraph;
 22 
 23 
 24 ALGraph *create_ALGraph(){
 25     
 26     int i,j,n;
 27     ALGraph *a = (ALGraph *)malloc(sizeof(ALGraph));
 28     ARCnode *p;
 29 
 30     printf("输入顶点数:\n");
 31     scanf("%d",&j);
 32     printf("输入边数:\n");
 33     scanf("%d",&n);
 34     
 35     a->vexnum = j;
 36     a->arcnum = n;
 37     
 38     for(i=0;i<a->vexnum;i++){
 39         a->vexnode[i].vexdata = i;
 40         a->vexnode[i].firstarc = NULL;
 41     }
 42     
 43     printf("\n");
 44     printf("输入边的信息:\n");
 45     for(i=0;i<a->arcnum;i++){
 46         scanf("%d %d",&j,&n);
 47         p = (ARCnode *)malloc(sizeof(ARCnode));
 48         p->adjvex = n;
 49         p->info = n;
 50         p->nextarc = a->vexnode[j].firstarc;
 51         a->vexnode[j].firstarc = p;
 52     }
 53     
 54     return a;
 55 }
 56 
 57 //深度优先遍历使用递归来遍历所有节点 
 58 void dfs(ALGraph a,int v){
 59     
 60     visited[v] = 1;                //访问过的顶点标识为1 
 61     printf("%d ",v);
 62     VEXnode vex = a.vexnode[v];
 63     ARCnode *arc = vex.firstarc;
 64     while(arc!=NULL){
 65         if(visited[arc->adjvex]==0)//判断是否访问过 
 66             dfs(a,arc->adjvex);    //访问该顶点的邻接点 
 67         arc = arc->nextarc;        //如果访问过,则退回到该节点,寻找没有被访问过的节点 
 68     }
 69     
 70 }
 71 
 72 //深度优先遍历函数 
 73 void dfs_trave(ALGraph a){
 74     
 75     int i;
 76     for(i=0;i<a.vexnum;i++)
 77         visited[i] = 0;            //标识数组,用来记录被访问过的顶点 
 78                                 //0代表没有访问过,1则反之 
 79     for(i=0;i<a.vexnum;i++)
 80         if(visited[i] == 0)
 81             dfs(a,i);
 82     
 83 }
 84 
 85 void display(ALGraph *a){
 86     
 87     printf("\n");
 88     
 89     int i,j;
 90     for(i=0;i<a->vexnum;i++){
 91         j = a->vexnode[i].vexdata;
 92         printf("%d ",j);
 93         ARCnode *arc = a->vexnode[i].firstarc; 
 94         while(arc!=NULL){
 95             printf("%d ",arc->adjvex);
 96             arc = arc->nextarc;
 97         }
 98         printf("\n");
 99     }
100     
101 }
102 
103 void main(){
104     
105     ALGraph *a = create_ALGraph();
106     display(a);
107 //    ALGraph alg = *a;
108 //    dfs_trave(alg);
109     
110 }
View Code

 

广度优先遍历

算法:访问某个顶点V1,然后把V1的所有邻接点全部访问,比如有V2、V3、V4。这就是一层,然后再访问V2的所有邻接点,接着访问V3、V4的所有邻接点。当然访问过的顶点不再需要访问了。

代码如下:广度遍历需要一个队列来暂时存储访问过得顶点。然后根据这个顶点来访问他的所有邻接点。

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #define max_len 100
  4 int visited[max_len];
  5 
  6 typedef struct{
  7     int data[max_len];
  8     int front,rear;
  9 }SeqQueue; 
 10 
 11 typedef struct node{
 12     int adjvex;
 13     struct node *nextarc;
 14     int info;
 15 }ARCnode; 
 16 
 17 typedef struct vexnode{
 18     int vexdata;
 19     ARCnode *firstarc;
 20 }VEXnode;
 21 
 22 typedef struct{
 23     VEXnode vexnode[max_len];
 24     int vexnum,arcnum;
 25 }AlGraph;
 26 
 27 SeqQueue *init_SeqQueue(){
 28     
 29     SeqQueue *sq = (SeqQueue *)malloc(sizeof(SeqQueue));
 30     sq->front = 0;
 31     sq->rear = 0;
 32     
 33     return sq;
 34 }
 35 
 36 int isEmpty(SeqQueue *sq){
 37     
 38     if(sq->front==sq->rear)
 39         return 1;
 40     return 0;
 41     
 42 }
 43 
 44 int delQueue(SeqQueue *sq){
 45     
 46     if(sq->rear==sq->front)
 47         return ;
 48     sq->rear = (sq->rear+1)%max_len;
 49     return sq->data[sq->rear];
 50     
 51 }
 52 
 53 void inQueue(SeqQueue *sq,int n){
 54     
 55     
 56     sq->front = (sq->front+1)%max_len;
 57     if(sq->rear==sq->front)
 58         return ;
 59     sq->data[sq->front] = n;
 60     
 61 }
 62 
 63 AlGraph *create_AlGraph(){
 64     
 65     int i,j,n;
 66     AlGraph *a = (AlGraph *)malloc(sizeof(AlGraph));
 67     ARCnode *p;
 68 
 69     printf("输入顶点数:\n");
 70     scanf("%d",&j);
 71     printf("输入边数:\n");
 72     scanf("%d",&n);
 73     
 74     a->vexnum = j;
 75     a->arcnum = n;
 76     
 77     for(i=0;i<a->vexnum;i++){
 78         a->vexnode[i].vexdata = i;
 79         a->vexnode[i].firstarc = NULL;
 80     }
 81     
 82     printf("\n");
 83     printf("输入边的信息:\n");
 84     for(i=0;i<a->arcnum;i++){
 85         scanf("%d %d",&j,&n);
 86         p = (ARCnode *)malloc(sizeof(ARCnode));
 87         p->adjvex = n;
 88         p->info = n;
 89         p->nextarc = a->vexnode[j].firstarc;
 90         a->vexnode[j].firstarc = p;
 91     }
 92     
 93     return a;
 94 }
 95 
 96  
 97 void bfs(AlGraph a,int v,SeqQueue *sq){
 98     
 99     printf("\n%d ",v);
100     visited[v] = 1;
101     inQueue(sq,v);            //被访问过的顶点入队列 
102     
103     int i;
104     while(!isEmpty(sq)){    //如果队列非空则继续访问 
105         i = delQueue(sq);    //寻找出队顶点的所有邻接点 
106         ARCnode *arc = a.vexnode[i].firstarc;
107         while(arc!=NULL){
108             if(visited[arc->adjvex]!=1){    
109                 printf("%d ",arc->adjvex);
110                 visited[arc->adjvex] = 1;    //标识为已被访问过 
111                 inQueue(sq,arc->adjvex);    //被访问过的顶点入队列 
112             }
113             arc = arc->nextarc;    
114         }
115     }
116     
117 }
118 
119 //广度优先遍历函数
120 void bfs_trave(AlGraph a,SeqQueue *sq){
121     
122     int i;
123     for(i=0;i<a.vexnum;i++)
124         visited[i] = 0;
125     
126     for(i=0;i<a.vexnum;i++){
127         if(visited[i] == 0)
128             bfs(a,i,sq);
129     }
130     
131 }
132 
133 void display(AlGraph *a){
134     
135     printf("\n");
136     
137     int i,j;
138     for(i=0;i<a->vexnum;i++){
139         j = a->vexnode[i].vexdata;
140         printf("%d ",j);
141         ARCnode *arc = a->vexnode[i].firstarc; 
142         while(arc!=NULL){
143             printf("%d ",arc->adjvex);
144             arc = arc->nextarc;
145         }
146         printf("\n");
147     }
148     
149 }
150 
151 
152 void main(){
153     
154     SeqQueue *sq = init_SeqQueue();
155     AlGraph *a = create_AlGraph();
156     display(a);
157     AlGraph alg = *a;
158     bfs_trave(alg,sq);
159     
160 }
View Code
posted @ 2020-01-06 11:00  捞的不谈  阅读(727)  评论(0编辑  收藏  举报