《数据结构》C++代码 邻接表与邻接矩阵

       上一篇“BFS与DFS”写完,突然意识到这个可能偏离了“数据结构”的主题,所以回来介绍一下图的存储:邻接表和邻接矩阵。

       存图有两种方式,邻接矩阵严格说就是一个bool型的二维数组,map[i][j]表示i到j有没有单向边,邻接表则是对1~N中每个点都拉出一个链表来,链表E[i]中存的每个点j都表示i到j有一条单向边。 这两种方式各有利弊,在稀疏图中,邻接表更好,省时间而且省空间;在稠密图中,邻接矩阵更好,不浪费时间的同时省去了指针域的空间。

       而实际写代码时,对于邻接矩阵,我们可能会考虑用int型的邻接矩阵来同时表达边的权值,这取决于具体情况;对于邻接表,我们在对每个点拉出一个链表时,可以实际分配一个一维数组作为表头,以简化删除边时的代码,同时方便存每个点的信息,也可以像本文代码中直接用指针来作为表头,省些空间。

       本文仅仅给出相对基本的代码,边上的信息仅有一个权值,想必这已经够了。如果信息增多,大家在同样的位置添加信息即可。另外,临界表在很多情况下是可以用静态内存来代替动态内存的,这个方法本文代码就不赘述了,方法同“线性表”一文中所述。

      注意!对于邻接表和邻接矩阵,我并未试过用类来写,在此仅仅给出一个很丑的类版代码,不是为了供大家参考,而是抛砖引玉,希望有高手能给出更好的类版实现代码,不胜感激!

清爽版:

const int maxn = 10000;

// 邻接矩阵
struct edge
{
    bool p; // p表示此边有无,也可以通过c取一个题目中不可能取到的值来代替p的作用
    int c;
    edge():p(false) {}
}map[maxn+1][maxn+1];
void Clear()
{
    for(int i=1;i<=maxn;++i)
        for(int j=1;j<=maxn;++j) map[i][j].p=false;
}
void AddEdge(int u,int v,int c)
{
    map[u][v].p=true; map[u][v].c=c;
}
void DelEdge(int u,int v)
{
    map[u][v].p=false;
}

// 邻接表
struct edge
{
    int v;
    int c;
    edge *next;
    edge(int _v=0,int _c=0): v(_v), c(_c) {}
}*E[maxn+1]; // 全局定义,初始便都是0;若在局部定义,则应先清0
void Clear()
{
    edge *p;
    for(int i=1;i<=maxn;++i)
        while(E[i])
        {
            p=E[i]; E[i]=p->next;
            delete p;
        }
}
void AddEdge(int u,int v,int c)
{
    edge *p=new edge(v,c);
    p->next=E[u]; E[u]=p;
}
void DelEdge(int u,int v)
{
    if(E[u]->v==v) { E[u]=E[u]->next; return; }
    for(edge *p=E[u],*q=p->next;q;p=q,q=p->next)
        if(q->v==v)
        {
            p->next=q->next;
            delete q;
            return; // 如果有重边,则此处不应返回,应待循环完再返回
        }
}

类版:

// 邻接表
struct edge
{
    int v;
    int c;
    edge *next;
    edge(int _v=0,int _c=0): v(_v), c(_c) {}
};

class Map
{
    static const int maxn = 10000;
    edge *E[maxn+1];
public:
    Map() { for(int i=1;i<=maxn;++i) E[i]=0; }
    void clear()
    {
        edge *p;
        for(int i=1;i<=maxn;++i)
            while(E[i])
            {
                p=E[i]; E[i]=p->next;
                delete p;
            }
    }
    void add(int u,int v,int c)
    {
        edge *p=new edge(v,c);
        p->next=E[u]; E[u]=p;
    }
    void del(int u,int v)
    {
        if(E[u]->v==v) { E[u]=E[u]->next; return; }
        for(edge *p=E[u],*q=p->next;q;p=q,q=p->next)
            if(q->v==v)
            {
                p->next=q->next;
                delete q;
                return; // 如果有重边,则此处不应返回,应待循环完再返回
            }
    }
    edge* begin(int u) { return E[u]; }
    edge* next(edge *p) { return p->next; }
}G;

时间: 2024-10-10 05:17:39

《数据结构》C++代码 邻接表与邻接矩阵的相关文章

算法导论--图的存储(邻接表与邻接矩阵)

转载请注明出处:勿在浮沙筑高台http://blog.csdn.net/luoshixian099/article/details/51888031 图的存储方法有邻接表.邻近矩阵.邻接多重表.十字链表等.本篇文章介绍两种简单且比较常用的两种方法:邻接表与邻接矩阵方法. 以下面的无向图为例,介绍两种存储方法.有向图的存储方法类似,只是边是单方向,无向图的边可以看做双向. 1.邻接链表法 邻接链表表示法对图中的每个顶点建立一个带头的边链表:第i条链表代表依附于顶点vi所有边信息,若为有向图,则表示

POJ 2387 Til the Cows Come Home dijkstra算法 用邻接表和邻接矩阵

题目如下: Til the Cows Come Home Time Limit: 1000MS        Memory Limit: 65536K Total Submissions: 27726        Accepted: 9353 Description Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wa

【算法与数据结构】图 -- 邻接表

/************************************************************************ 边(弧)结点 -------------------------- |adjvex | info | nextarc | -------------------------- adjvex:邻接点域,该点在图中的位置 info :相关信息,比如可以保存从某顶点到该点的权值 nextac:指向下一个与该点有相同邻接点的顶点 顶点结点 ---------

邻接表和邻接矩阵手写简洁代码DFS BFS

这是通过邻接矩阵进行DFS #include<iostream> #include<string> #include<windows.h> #define Max_ver_num 20 using namespace std ; bool visit[Max_ver_num] ;//这个数组的用途是标记 struct HGraph{ string vexs [ Max_ver_num ] ; //放每个顶点的数组的名字 int arcs [Max_ver_num][Ma

邻接表转邻接矩阵

假设无向图G采用邻接矩阵存储,编写一个算法输出邻接表. Description 第一行为一个整数n,表示顶点的个数(顶点编号为0到n-1),接下来是为一个n*n大小的整数矩阵,表示图的邻接关系.数字为0表示不邻接,1表示邻接. Input 输出图G的邻接表.第一行表示顶点0可直接到达的顶点编号.其他行定义相同. Output 1 2 3 4 5 6 5 0 1 0 1 1 1 0 1 1 0 0 1 0 1 1 1 1 1 0 1 1 0 1 1 0 Sample Input 1 2 3 4 5

图的邻接表和邻接矩阵 没写完放着。。

#include <iostream> #include <memory.h> #include <stack> #include <queue> using namespace std; class GraphList; //边结点的结构体 struct Edge { friend class GraphList; int VerAdj; //邻接顶点序号,从0开始编号 int cost; //边的权值 Edge*Link; //指向下一边节点的指针 Ed

第六章部分例题 双向bfs邻接表和邻接矩阵实现

Idealpath 双向bfs输出颜色,邻接矩阵实现 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <map> 6 #include <algorithm> 7 8 using namespace std; 9 10 const int maxn=10000; 11 const int inf=1

看数据结构写代码(36) 图的邻接表表示与实现

图的邻接表表示法,是为每一个顶点建立一个链表,链表里存放着相同弧尾的 弧的信息,这些链表顺序存放在数组中.下面是无向图g2的邻接表 邻接表 比 邻接矩阵 节省空间,同时 也带来一些操作上的 不便,例如 看 两个顶点是否 相邻,需要 遍历 链表,在 求 无向图顶点的度时,只需 遍历 顶点的链表,而 求 有向图 顶点的度 需要 遍历 整个图 查找 弧头 为这个顶点的 个数. 如果 不想这样做,可以 建立 逆邻接表,即 链表里 存放着 相同 弧头的 弧 的信息. 下一节 要说的 十字链表 类似于这种结

数据结构----邻接矩阵-邻接表

要表示一个图G=(V,E),有两种标准的表示方法,即邻接表和邻接矩阵.这两种表示法既可用于有向图,也可用于无向图.通常采用邻接表表示法,因为用这种方法表示稀疏图(图中边数远小于点个数)比较紧凑.但当遇到稠密图(|E|接近于|V|^2)或必须很快判别两个给定顶点手否存在连接边时,通常采用邻接矩阵表示法,例如求最短路径算法中,就采用邻接矩阵表示. #include<stdio.h> #include<string.h> #include <stdlib.h> #define