图与树的存储方式

邻接表方式

head与nex数组中保存的是ver(vertex)数组的下标,相当于指针,其中0表示指向空。ver数组中存储的是每条边的终点,是真实的图数据。也可以将head与nex数组看作存放边的编号(即tot)。

#include<cstdio>
const int MAXN = 100010;
int head[MAXN],ver[MAXN],edge[MAXN],nex[MAXN];
int tot = 1;
//分别代表表头、终点、边权
void addEdge(int x,int y,int z){
    ver[++tot] = y, edge[tot] = z;
    nex[tot] = head[x],head[x] = tot;//在表头x处插入
}

int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= m;i++){
        int from,to,val;
        scanf("%d%d%d",&from,&to,&val);
        addEdge(from,to,val);
        addEdge(to,from,val);
    }
    //访问从x出发的所有边
    int x = 2;
    for(int i = head[x];i;i = nex[i]){
        int y = ver[i],z = edge[i];
        //找到一条有向边x->y,权值为z
        printf("%d %d %d\n",x,y,z);
    }
    return 0;
}
前向星和链式前向星

前向星是一种数据结构,以存储边的形式存储图。先读入边并存储在连续的数组中,然后对数组按照起点进行排序。这样数组中起点相同的点就可以连续访问了。优点是实现简单,容易理解,缺点是需要排序,适合离线。
链式前向星和邻接表类似,也是链式结构和线性结构的结合。每个节点x对应一个链表,链表中存放从x出发的边的集合。
我们采用Edge结构体来存储边,并使用head数组存储头节点,于是我们就可以根据head[x]来访问从x出发的所有边,访问方法同邻接表。每次插入节点时间复杂度为O(1),对于稀疏图与稠密图效果都很好。

struct Edge{
    int from,to,val,nex;
    Edge(){}
    Edge(int from,int to,int val,int nex):
    from(from),to(to),val(val),nex(nex){}
}edges[MAXM];
int head[MAXN],tot = 1;
void addEdge(int from,int to,int val){
    edges[++tot] = Edge(from,to,val,head[from]);
    head[from] = tot;
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师:白松林 返回首页