Graph

在数据结构中,图的构造一般为2种:
1)邻接矩阵(稠密图) 二维数组:
无向图:对称(主对角线)
有向图:不对称

2) 邻接表(稀疏图) 一维数组链表:
无向图:一张邻接表
有向图:2张邻接表(出度表、入度表)

一般构造步骤(选择):
1)邻接矩阵 与 邻接表
2)有向图 与 无向图
3) 无权边 与 有权边

邻接矩阵:无向图、无权边

#include<iostream>
using namespace std;

#define N 100

struct Node
{
    char data;  
};

struct Graph
{
    int vexnum;
    int arcnum;
    Node node[N]; // N个顶点信息
    int matrix[N][N];
};

int Loc_vec(Graph G,char a)
{
    for(int i=1;i<=G.vexnum;i++)
    {
        if(G.node[i].data == a)
        {return i;
        }
    }
}

void Input(Graph &G)
{
    cin>>G.vexnum>>G.arcnum;
    for(int i=1;i<=G.vexnum;i++)
    {
        for(int j=1;j<=G.vexnum;j++)
        {
            G.matrix[i][j] = 0;
        }
    }
    for(int i=1;i<=G.vexnum;i++)
    {
        cin>>G.node[i].data;
    }
    char a,b;
    for(int i=1;i<=G.arcnum;i++)
    {
        cin>>a>>b;
        int x = Loc_vec(G,a);
        int y = Loc_vec(G,b);
        G.matrix[x][y] = G.matrix[y][x] = 1;
    }
}


void Output(Graph G)
{
    for(int i=1;i<=G.vexnum;i++)
    {
        for(int j=1;j<=G.vexnum;j++)
        {
            if(G.matrix[i][j]==1)
            {
                cout<<G.node[i].data<<" "<<G.node[j].data<<endl;
                G.matrix[j][i] = 0;
            }
        }
    }
}

int main()
{
    Graph G;
    Input(G);
    cout<<"Output:"<<endl;
    Output(G);
    return 0;
}

邻接表:无向图,有权边

// 邻接: adjoin 
// AdjList

#include<iostream>
using namespace std;

#define N 100

struct Enode{  // 每个顶点的链表 
    int loc;  // 在顶点AdjList[N]中的位置 
    struct Enode *next;
    int weight;
};

struct Vnode{  // 一维顶点信息 
    char data;
    Enode *first;
};

struct Graph{
    int vexnum;
    int arcnum;
    Vnode AdjList[N];
};


int Loc_vex(Graph G,char a)
{
    for(int i=1;i<=G.vexnum;i++)
    {
        if(G.AdjList[i].data == a)
        {return i;
        }
    }
}

void Input(Graph &G)
{
    cin>>G.vexnum>>G.arcnum;
    for(int i=1;i<=G.vexnum;i++)
    {
        cin>>G.AdjList[i].data;
        G.AdjList->first = NULL;
    }
    char a,b;
    int w;
    for(int i=1;i<=G.arcnum;i++)
    {
        cin>>a>>b>>w;
        int x,y;
        x = Loc_vex(G,a);
        y = Loc_vex(G,b);
        // a->b
        Enode *p = new Enode;
        p->loc = y;
        p->weight = w;
        p->next = NULL;
        G.AdjList[x].first = p;
        // b->a
        Enode *q = new Enode;
        q->loc = x;
        q->weight = w;
        q->next = NULL;
        G.AdjList[y].first = q; 
    }
}

void Output(Graph &G)
{
    for(int i=1;i<=G.vexnum;i++)
    {
        cout<<G.AdjList[i].data<<" ";
        Enode *p;
        p = G.AdjList[i].first;
        while(p)
        {
            cout<<G.AdjList[p->loc].data<<" "<<p->weight<<endl;
            p = p->next;
        }
    }
}

int main()
{
    Graph G;
    Input(G);
    Output(G);
    return 0;
}

图的基础是遍历: bfs,dfs

图的应用也有多种:

1.最小生成树(Prim,Kruskal):
一般为带权无向图,求任意2个点都连通时,最小的权值和
例如:要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。

2.最短路径(dijkstra , Floyd):
dijkstra:某点到其余各点的最短路径。
Floyd:任意两点之间最短路径。

3.拓扑排序:
检测图中是否有环,也就是求某个点的前驱路径。若无环,则所有顶点都在它的拓扑有序序列中,即能完成拓扑排序
DAG:有向无环图
AOV网 (不能出现有向环):顶点表示活动,边表示先后关系的有向无环图

4.求关键路径:
AOE网:边表示活动,带权有向无环图
也需要用到拓扑排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值