《大话数据结构》图。2018-8-3-8-6

数据元素。线性表中叫元素和空表,树中叫结点和空树、图中叫顶点。

无向边:若顶点v1到v2之间的边没有方向,则称这条边为无向边,用无序偶对(v1,v2)来表示。如果任意两点的边都没有方向则为无向图。如果任意两点都有边,则称为无向完全图。

n个顶点的无向完全图有nx(n-1)/2条边。

有向边:顶点v1到v2有方向。则叫有向边,也称为弧{Arc}。<v1,v2>来表示,v1称为弧尾,v2为弧头。不能写成<v2,v1>如果任意两点的边都有方向则为有向图。任意两点都存在互为相反的两条弧,则称为有向完全图。

n个顶点的有向完全图有nx(n-1)条边。

有很少条边或弧的图为稀疏图,反之为稠密图。带权的图通常为网。

子图:一个图是另一个图的一部分(有向就也要看方向),那他就是子图。

无向图。v1和v2有连边,则俩互为邻接点,则连边依附于俩点。

度:一个顶点v周围的边。TD(v)

图的存储结构:

1.邻接矩阵。图由顶点和弧或便组成。用两个数组。一个数组存储图中顶点信息,一个二维数组存储图中的边或弧。

arc[0][1]=1,v0-v1有边。对称矩阵

不对称。顶点v1的列是入度1,行是出度2。

无穷大表示没有这边,不用0是因为有些比边的权值可能为0,怕混。

/*前面的结构定义不写了*/
void creategraph( MGraph *G)
{
    int i, j, k, w;
    printf("输入定点数和边数:\n");
    scanf("%d,%d", &G->numVertexes, &G->numEdages); /*输入顶点和边数*/
    for( i = 0; i<G->numVertexes; i++ ) /*读入顶点信息,建立定点表*/
        scanf( &G->vexs[i] );
    for()
}

后面太多不想抄了,百度吧

邻接表。图中顶点用一个一维数组存储,每个顶点的所有邻接点构成一个线性表,由于邻接点个数不确定,用单链表。

data:顶点。firstedge:第一个邻接点的指针,adjvex:某顶点的邻接点在data中的下标:next:data的另一个节点的指针。

/*结点定义*/

typedef char VertexType;    /*顶点类型*/
typedef int EdgeType;      /*边上权值类型*/

typedef struct EdgeNode
{
    int adjvex;
    EdgeType Weight;
    struct EdgeType *next;
}EdgeNode;

typedef struct VertexNode
{
    VertexType data;
    EdgeNode *firstedge;
}vertexNode, AdjList[MAXVEX];

typedef struct
{
    AdjList adjList;
    int numVertexes, numEdges;
}GraphAdjList;

创建一个邻接表无向图的。

void CreateALGraph(GraphAdjList *G)
{
    int i, j, k;
    EdgeNode *e;
    printf("输入顶点和边数:\");
    scanf("%d,%d",&G->numVertexes,&G->numEdge);
    for(i=0;i<numVertexes;i++)     /*建立顶点列表*/
        {
            scanf(&G->adjList[i].data);
            G->adjList[i].firstedge=NULL;
        }
    for(k=0;k<G->numEdges;k++)    /*建立边表、权值*/
        {
            printf("输入边(vi,vj)上的顶点序号:\n")
            scanf("%d,%d",&i,&j);    
            e=(EdgeNode *)malloc(sizeof(EdgeNode));  /*结点*/
            e->adjvex=j;   /*邻接点序号*/
            e->next=G->adjList[i].firstedge;      /*将e指针指向当前顶点指向的结点*/
            G->adjList[i].firstedge=e;     /*将当前顶点的指针指向e*/
            /*无向图,i、j有两个*/
            e=(EdgeNode *)malloc(sizeof(EdgeNode));  /*结点*/
            e->adjvex=i;   /*邻接点序号*/
            e->next=G->adjList[j].firstedge;      /*将e指针指向当前顶点指向的结点*/
            G->adjList[j].firstedge=e;     /*将当前顶点的指针指向e*/            
        }
}

图的遍历:

设置一个visited[n],n是图中顶点的个数,初值为0,访问过了就为1。好比迷宫里拿刀刻上记号。

深度优先遍历:深度优先搜索DFS。

从图中某个顶点v出发,从v的未被访问的邻接点出发,深度优先遍历图,直至图中所有和v有路径相同的顶点都被访问到。

typedef int Boolean;     /*布尔类型,TRUE FALSE*/
Boolean visited[Max];
void DFS(MGraph G, int i)
{
    int j;
    visited[i]=TRUE;
    printf("%c",G.vexs[i])    /*打印顶点*/
    for(j=0;j<G.numVer;j++)          /*->是指针用的*G,  .  是普通的用的G*/
        if(G.arc[i][j]==1 && !visited[j])
            DFS(G,j);
}
void DFSTraverse(MGraph G)
{
    int i;
    for(i=0;i<G.numVertexes;i++)
        visited[i]=FALSE;   /*初始所有顶点状态都是未访问过状态*/
    for(i=0;i<G.numVertexes;i++)
        if(!visited[i])
            DFS[G,i]
}

完整代码https://blog.csdn.net/qq_22238021/article/details/78286798

就看这么多吧先,周一比较困,看看工程吧,学术看不进去了。

猜你喜欢

转载自blog.csdn.net/weixin_41982696/article/details/81388762