zoukankan      html  css  js  c++  java
  • 图->存储结构->十字链表

    文字描述

      十字链表是有向图的另一种链式存储结构. 在十字链表中,对应于有向图中每一条弧有一个结点,对应于每个顶点也有一个结点.这些结点的结构如下所示:

      在弧结点中有5个域: 尾域tailvex和头域headvex分别指示弧尾和弧头这两个顶点在图中的位置,链域hlink指向与弧头相同的下一条弧, 而链域tlink指向弧尾相同的下一条弧, info域指向该弧的相关信息; 弧头相同的弧在同一链表上, 弧尾相同的弧也在同一链表上. 它们的头结点即为顶点结点,它由3个域组成:其中data域存储和顶点相关的信息,如顶点名称等; firstin和firstout为两个链域,分别指向以该顶点为弧头或弧尾的第一个弧结点.

    示意图

    算法分析

      建立十字链表的时间复杂度和建立邻接表是相同的. 而且在十字链表中既容易找到以vi为尾的弧,也容易找到以vi为头的弧,因而容易求得顶点的出度和入度.

    代码实现

      1 /*
      2     以十字链表作为图的存储结构创建图。
      3 */
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <string.h>
      7 
      8 #define    MAX_VERTEX_NUM    20    //最大顶点数
      9 #define DEBUG
     10 typedef enum {DG, DN, UDG, UDN} GraphKind; //{有向图,有向网,无向图,无向网}
     11 typedef char InfoType;
     12 typedef char VertexType;
     13 //弧结点
     14 typedef struct ArcBox{
     15     int tailvex, headvex;//该弧的尾和头顶点的位置
     16     struct ArcBox *hlink, *tlink;//分别为弧头相同和弧尾相同的弧的链域
     17     InfoType *info;//该弧相关的信息
     18 }ArcBox;
     19 //顶点结点
     20 typedef struct VexNode{
     21     VertexType data;//顶点名称
     22     ArcBox *firstin, *firstout;//分别指向该顶点第一条入弧和出弧
     23 }VexNode;
     24 typedef struct{
     25     VexNode xlist[MAX_VERTEX_NUM];//表头向量
     26     int vexnum, arcnum;//有向图的当前顶点数和弧数
     27     GraphKind kind;//图类型
     28 }OLGraph;
     29 
     30 /*
     31     若G中存在顶点u,则返回该顶点在图中位置;否则返回-1。
     32 */
     33 int LocateVex(OLGraph G, VertexType v)
     34 {
     35     int i = 0;
     36     for(i=0; i<G.vexnum; i++){
     37         if(G.xlist[i].data == v)
     38             return i;
     39     }
     40     return -1;
     41 }
     42 
     43 /*
     44     若G中存在顶点位置loc存在,则返回其顶点名称
     45 */
     46 VertexType LocateVInfo(OLGraph G, int loc)
     47 {
     48     return G.xlist[loc].data;
     49 }
     50 
     51 /*
     52     采用十字链表的存储结构,构造有向图
     53  */
     54 int CreateDG(OLGraph *G)
     55 {
     56     int i = 0, j = 0, k = 0, IncInfo = 0;
     57     int v1 = 0, v2 = 0;
     58     char tmp[10] = {0};
     59     ArcBox *p = NULL;
     60 
     61     printf("输入顶点数,弧数,其他信息标志位: ");
     62     scanf("%d,%d,%d", &G->vexnum, &G->arcnum, &IncInfo);
     63 
     64     for(i=0; i<G->vexnum; i++){
     65         //输入顶点值
     66         printf("输入第%d个顶点: ", i+1);
     67         memset(tmp, 0, sizeof(tmp));
     68         scanf("%s", tmp);
     69         //初始化指针
     70         G->xlist[i].data = tmp[0];
     71         G->xlist[i].firstin = NULL;
     72         G->xlist[i].firstout = NULL;
     73     }
     74     
     75     //输入各弧并构造十字链表
     76     for(k=0; k<G->arcnum; k++){
     77         printf("输入第%d条弧(顶点1, 顶点2): ", k+1);
     78         memset(tmp, 0, sizeof(tmp));
     79         scanf("%s", tmp);
     80         sscanf(tmp, "%c,%c", &v1, &v2);
     81         //确定顶点v1和v2在图中的位置
     82         i = LocateVex(*G, v1);    
     83         j = LocateVex(*G, v2);
     84         //对弧结点赋值
     85         p = (ArcBox *) malloc(sizeof(ArcBox));
     86         p->tailvex = i;
     87         p->headvex = j;
     88         p->hlink = G->xlist[j].firstin;
     89         p->tlink = G->xlist[i].firstout;
     90         p->info = NULL;
     91         //完成在入弧和出弧链头的插入
     92         G->xlist[j].firstin = p;
     93         G->xlist[i].firstout = p;
     94         //若弧有相关的信息,则输入
     95         if(IncInfo){
     96             //Input(p->info);
     97         }
     98     }
     99     return 0;
    100 }
    101 
    102 /*
    103     采用十字链表的存储结构,构造图
    104 */
    105 int CreateGraph(OLGraph *G)
    106 {
    107     printf("输入图类型: +有向图(0), -有向网(1), -无向图(2), -无向网(3): ");
    108     scanf("%d", &G->kind);
    109     switch(G->kind){
    110         case DG:
    111             return CreateDG(G);
    112         case DN:
    113         case UDN:
    114         case UDG:
    115         default:
    116             printf("还不支持!
    ");
    117             return -1;
    118     }
    119 }
    120 
    121 /*
    122     输出图的信息
    123 */
    124 void printG(OLGraph G)
    125 {
    126     if(G.kind == DG){
    127         printf("类型:有向图;顶点数 %d, 弧数 %d
    ", G.vexnum, G.arcnum);
    128     }else if(G.kind == DN){
    129         printf("类型:有向网;顶点数 %d, 弧数 %d
    ", G.vexnum, G.arcnum);
    130     }else if(G.kind == UDG){
    131         printf("类型:无向图;顶点数 %d, 弧数 %d
    ", G.vexnum, G.arcnum);
    132     }else if(G.kind == UDN){
    133         printf("类型:无向网;顶点数 %d, 弧数 %d
    ", G.vexnum, G.arcnum);
    134     }
    135 
    136     int i = 0;
    137     ArcBox *fi = NULL;
    138     ArcBox *fo = NULL;
    139     for(i=0; i<G.vexnum; i++){
    140         printf("%c: ", G.xlist[i].data);
    141         fi = G.xlist[i].firstin;
    142         fo = G.xlist[i].firstout;
    143         printf("(hlink=");
    144         while(fi){
    145 #ifdef DEBUG
    146             printf("%c->%c; ", LocateVInfo(G, fi->tailvex), LocateVInfo(G, fi->headvex));
    147 #else
    148             printf("%d->%d; ", fi->tailvex, fi->headvex);
    149 #endif
    150             fi = fi->hlink;
    151         }
    152         printf(")	(tlink=");
    153         while(fo){
    154 #ifdef DEBUG
    155             printf("%c->%c; ", LocateVInfo(G, fo->tailvex), LocateVInfo(G, fo->headvex));
    156 #else
    157             printf("%d->%d; ", fo->tailvex, fo->headvex);
    158 #endif
    159             fo = fo->tlink;
    160         }
    161         printf(")
    ");
    162     }
    163     return;
    164 }
    165 
    166 int main(int argc, char *argv[])
    167 {
    168     OLGraph G;
    169     if(CreateGraph(&G) > -1){
    170         printG(G);
    171     }
    172     return 0;
    173 }
    十字链表存储结构(图)

    代码运行

  • 相关阅读:
    用户模式同步之互斥体小解
    用户模式同步之信号量小解
    用户模式同步之事件小解
    中断和异常
    断点之软件断点的一些基本知识(INT3)
    部署Django项目Nginx + uwsgi
    CentOS切换root用户一直提示Incorrect password
    一张图看懂Mysql的join连接
    Nginx部署入门
    Django使用多个数据库
  • 原文地址:https://www.cnblogs.com/aimmiao/p/9737668.html
Copyright © 2011-2022 走看看