1----------图(邻接矩阵)的相关算法

走进算法世界的大门,发现算法中的奥秘,让我们一起来探险吧。

图的邻接矩阵结构体定义

图的邻接矩阵结构体定义

typedef struct{ 
    int no;
    char data;//存放顶点信息
}Node;

typedef struct{
    int edges[maxSize][maxSize];    //边表
    Node nodes[maxSize];    //顶点表
    int n,e;    //n表示顶点数,e表示边数
}MGraph;

1.图的邻接矩阵的结构体,实际上就是一个二维数组,当二维数组中值为0时,表示中间没有边,值为1时,表示有边
2.若想保存全值,那么将0改成无穷,我们用一个最大整形的数字(65535)代替即可,其他有边的地方,将1改成想对应的权值


图(邻接矩阵)的建立算法

实际上,要建立邻接矩阵,那么就是建立一个二维数组,要注意的一点是无向图的矩阵表示是对称的

void createMGraph(MGraph * G){
    int i,j,k,w;
    printf("分别输入顶点数和边数:\n");
    scanf("%d,%d",&G->n,&G->e);
    printf("输入顶点表信息:\n");
    for(i=0;i<G->n;i++){    
        G->nodes[i].no = i;
        scanf("%c",&G->nodes[i].data);  //录入顶点信息,若题干中不做要求,则可省去
    }
    for(i=0;i<G->n;i++){    //初始化边表
        for(j=0;j<G->n;j++){
            G->edges[i][j] = INF;
        }
    }
    for(k=0;k<G->e;k++){
        printf("输入边(vi,vj)的下标和权值\n");
        scanf("%d,%d,%d",&i,&j,&w);
        G->edges[i][j] = w;
        G->edges[j][i] = w; //对称,所以权值一样
    }
}

图(邻接矩阵)的深度优先遍历算法

邻接矩阵的深度优先遍历算法,其实就是回溯法,通俗的理解回溯法,有点类似于迷宫,我们一条道走到死,不行就退回到上一个岔路口,再走
而邻接矩阵的深度优先遍历算法,其实跟迷宫一样,我们遍历该结点与之有关联的结点,若该结点与其他结点连同,就让其移动那个结点,再重复,如果走不通了,就回溯,回溯法通常是用递归实现

int visited[maxSize];   //用一个数组来记录是否访问过该顶点
void DFS(MGraph * G,int i){
    int j;
    visited[i] = 1;
    printf("%c",G->nodes[i].data);  //先遍历该结点
    for(j=0;j<G->n;j++){
        if(G->edges[i][j] != INF && !visited[j]){   //如果i和j有边的话,就移动到j顶点
            DFS(G,j);
        }
    }
}

void DFSTraverse(MGraph * G){
    int i;
    for(i=0;i<G->n;i++){
        visited[i] = 0; //初始化为为标记状态
    }
    for(i=0;i<G->n;i++){//对每一个结点进行遍历,这个循环主要用来处理非连通图
        if(!visited[i]){
            DFS(G,i);   //若是连连通,那`
只会调用一次
        }
    }
}

图(邻接矩阵)的广度优先遍历算法

图的广度优先遍历算法的核心思想是探测法,将与该顶点直接相连的顶点依次探测,探测后入队,并标记,标记后的点不再被访问,队列不空,则出队,再出队的点进行依次与之相关的探测,为什么要用到队列???原因是队列可以严格控制遍历顺序,是一层一层往外遍历的

void BFSTraverse(MGraph * G){
    int i,j,k;
    int que[maxSize];
    int front = 0,rear = 0;
    for(i=0;i<G->n;i++){    
        visited[i] = 0; //初始化所以顶点未被标记
    }
    for(i=0;i<G->n;i++){    //若是连通图,该层循环可直接省去
        if(!visited[i]){
            printf("%c",G->nodes[i].data);  //先遍历该结点
            rear = (rear+1)%maxSize;
            que[rear] = i;
            visited[i] = 1;         //标记该结点
            while(rear != front){
                front = (front+1)%maxSize;
                k = que[front];
                for(j=0;j<G->n;j++){
                    if(G->edges[k][j]!= INF &&!visited[j]){
                        printf("%c",G->nodes[j].data);
                        rear = (rear + 1)%maxSize;
                        que[rear] = j;
                        visited[j] = 1;
                    }
                }
            }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值