最小生成树与DFS

1、普里姆算法:https://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html

2、Prim算法核心:在当前已经遍历到的权值中选择最小的权值生成树

3、克鲁斯卡尔算法核心:将权值从小到大依次选取相应的边,并且判断这两个点是否属于同一个连通分量。

4、深度优先搜索(DFS)核心:建立visited数组判断结点是否遍历到。

#include <stdio.h>
#include <string.h>

#define MAXVALUE       100
#define INITVALUE      65535

typedef struct
{
    char vexs[MAXVALUE];
    int arc[MAXVALUE][MAXVALUE];
    int numVexs, numArc;
}MGraph;

int visited[MAXVALUE];     //定义是否遍历过的点的数组标志位

void CreatGraph (MGraph *G)
{
    int i, j, k, weight;
    printf("Enter numVexs & numArc:");
    scanf("%d%d", &(G->numVexs), &(G->numArc));
    for(i = 0; i < G->numVexs; i++)
    {
        printf("Enter %d vex:", i);
        getchar();
        scanf("%c", &(G->vexs[i]));
    }
    for(i = 0; i < G->numVexs; i++)             //邻接矩阵初始化
    {
        for(j = 0; j < G->numVexs; j++)
        {
            G->arc[i][j] = INITVALUE;
        }
    }
    for(k = 0; k < G->numArc; k++)
    {
        printf("Enter i, j, weight:");
        scanf("%d%d%d", &i, &j, &weight);
        G->arc[i][j] = weight;
        G->arc[j][i] = weight;
    }
}

void DFS (MGraph *G, int i)
{
    int j;
    visited[i] = 1;
    printf("%c\n", G->vexs[i]);
    for(j = 0; j < G->numVexs; j++)
    {
        if(G->arc[i][j] != INITVALUE && !visited[j])
        {
            DFS(G, j);               //对未遍历的结点进行DFS     
        }
    }
}

void DFSTravers (MGraph *G)
{
    int i;
    for(i = 0; i < G->numVexs; i++)
    {
        visited[i] = 0;
    }
    for(i = 0; i < G->numVexs; i++)
    {
        if(!visited[i])
        {
            DFS(G, i);    //如果是连通图,则只需要DFS一次
        }
    }
}

void PrintGraph (MGraph *G)
{
    int i, j;
    for(i = 0; i < G->numVexs; i++)
    {
        for(j = 0; j < G->numVexs; j++)
        {
            printf("%d ", G->arc[i][j]);
        }
        printf("\n");
    }
}

void MiniSpanTree (MGraph G)
{
    int i, j, minval, k;
    int adjvex[MAXVALUE];         //定义数组,存储权值边的起点下标
    int lowest[MAXVALUE];         
    lowest[0] = 0;
    adjvex[0] = 0;
    for(i = 1; i < G.numVexs; i++)
    {
        adjvex[i] = 0;
        lowest[i] = G.arc[0][i];
    }
    for(i = 0; i < G.numVexs; i++)
    {
        minval = INITVALUE;
        j = 1;
        k = 0;
        while(j < G.numVexs)                    //找到当前边中权值最小的边
        {
            if(lowest[j] < minval && lowest[j] != 0)
            {
                minval = lowest[j];
                k = j;
            }
            j++;
        }
        lowest[k] = 0;
        printf("(%d %d)", adjvex[k], k);
        for(j = 1; j < G.numVexs; j++)                   //将权值较小的边加入Lowest数组中
        {
            if(G.arc[k][j] < lowest[j] && lowest[j] != 0)
            {
                lowest[j] = G.arc[k][j];
                adjvex[j] = k;
            }
        }

    }
}

int main ()
{
    MGraph G;
    CreatGraph(&G);
//    DFSTravers(&G);
//    PrintGraph(&G);
    MiniSpanTree(G);
    return 0;
}

  
  
#include <stdio.h> #include <algorithm> using namespace std;
#define MAXVALUE     50
typedef struct        //边集结点 {     int begin;     int end;     int weight; }Edge;
typedef struct {     Edge E[MAXVALUE];     int numArcs, numVex; }Graph;
int camp(Edge a, Edge b) {     return a.weight < b.weight; }
void CreatGraph (Graph *G) {     int k;     printf("Enter numVex && numArcs:");     scanf("%d%d", &(G->numVex), &(G->numArcs));     for(k = 0; k < G->numArcs; k++)     {         printf("Enter i, j, weight:");         scanf("%d%d%d", &(G->E[k].begin), &(G->E[k].end), &(G->E[k].weight));     }     sort(&(G->E[0]), &(G->E[k]), camp); }
void PrintGraph (Graph G) {     int i;     for(i = 0; i < G.numArcs; i++)     {         printf("(%d %d)%d ", G.E[i].begin, G.E[i].end, G.E[i].weight);     } }
int Find (int *parent, int f) {     while(parent[f] > 0)     {         f = parent[f];     }     return f; }
void KruskalSpanTree (Graph G) {     int parent[MAXVALUE], i, m, n;     for(i = 0; i < G.numVex; i++)     {         parent[i] = 0;     }     for(i = 0; i < G.numVex; i++)        {         m = Find(parent, G.E[i].begin);         n = Find(parent, G.E[i].end);         if(m != n)        //判断目前生成的树是否连通         {             parent[m] = n;             printf("(%d %d) ", G.E[i].begin, G.E[i].end);         }     } }
int main () {     Graph G;     CreatGraph(&G); //    PrintGraph(G);     KruskalSpanTree(G);     return 0; }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值