图的邻接表形式,加深印象,例图:

 

图的邻接表的表示方法_头结点

    数据结构书上表示邻接表比较复杂,一般形式如下:


Cpp代码  

图的邻接表的表示方法_邻接表_02



  1. typedef struct
  2. {
  3. int dest;                   //邻接边的弧头结点序号
  4. int weight;                 //权值信息
  5. struct Node *next;          //指向下一条邻接边
  6. }Edge;                          //单链表结点的结构体

  7. typedef struct
  8. {
  9. //结点的一些数据,比如名字
  10. int sorce;                  //邻接边的弧尾结点序号
  11. //邻接边头指针
  12. }AdjHeight;                     //数组的数据元素类型的结构体

  13. typedef struct
  14. {
  15. //邻接表数组
  16. int numOfVerts;             //结点个数
  17. int numOfEdges;             //边个数
  18. }AdjGraph;                      //邻接表结构体


 

    其实有种简洁且高效的表示形式:


Cpp代码 



  1. typedef struct
  2. {
  3. int
  4. int
  5. int
  6. }Edge;
  7. Edge e[MAX];
  8. int

  9. //初始化
  10. memset(pre,-1,sizeof(pre));

  11. //输入
  12. scanf("%d %d %d",&from,&to,&w1);
  13. e[i].to = to; e[i].w = w1; e[i].next = pre[from]; pre[from] = ++i;  或:
  14. struct node
    {
    int to;
    int _next;
    } edge[N];

    void add_edge(int u,int v)
    {
    edge[tot].to=v;
    edge[tot]._next=head[u];
    head[u]=tot++;
    }


上面这段代码中,边的结构体Edge由三个元素组成:弧头结点序号,边权值,下一条边的序号。e[i]指的是第i条边。pre[i]记录的是从当前输入的情况来看,序号为i的弧尾结点发出的第一条边的序号是pre[i]。

    这样,在操作某个结点发出的边时,可以像这么做:


Cpp代码 



  1. /*now为弧尾结点序号,i为now所发出的边序号,adj为弧头结点序号,w为now-->adj这条边的权值*/
  2. for(i = pre[now]; i != -1; i = edge[i].next)
  3. {
  4. int
  5. int
  6. //do something...
  7. }


   

哈希表这类的存储结构(链表法解决冲突),与图的邻接表类似,也可以用类似的表示方法:


Cpp代码 



  1. typedef struct
  2. {
  3. char e[11];    //value
  4. char f[11];     //key
  5. int next;        //下一个结果(hash冲突)
  6. }Entry;
  7. Entry entry[M];
  8. int hashIndex[M];   //哈希值为M的结果集的第一个在entry中的序号。

  9. //输入:对key进行hash,
  10. sscanf(str,"%s %s",entry[i].e,entry[i].f);
  11. int
  12. entry[i].next = hashIndex[hash];
  13. hashIndex[hash] = i;
  14. i++;

  15. //使用:
  16. for(int
  17. {
  18. //do something..
  19. }