关于图的一些定义和表示

一些定义:

一个(Gragh)G = (V,E)由定点(Vertex)集V和边(Edge)集E组成。

图的每一条边都是由一个对点(v,w)组成的。如果点是有序的,那么图就叫做有向图
反之则图为无向图

如果在一个无向图种从每一个顶点到每个其他顶点都存在一条路径,则称该无向图是连通的。具有这样的性质的有向图是强连通的。如果一个有向图不是强连通,但是他的基础图(其弧上去掉方向所形成的图)是连通的,那么该有向图称为弱连通的。
完全图是其每一个顶点间都存在一条边的图。

一条弧两端的两个顶点存在邻接关系
我们可以根据点的邻接关系画出邻接矩阵
那么表示图的第一种方法就是用邻接矩阵来实现。

如图

这里写图片描述

我们用1来表示两点之前存在关系,用0表示没有关系。
但是如果是带权图,我们可以置他们之间的关系值为权值,而没有邻接关系的两点之间的初始化需要根据实际情况来定。
例如:图代表了飞机的航线,寻找两个城市之间的最短航线。既然是寻找最短,那么我们就应该将没有邻接关系的权设置为∞。那假设是寻找最长的那条航线,我们就应该将其设置为-∞。

这种算法最容易实现方式当然是用二维数组存储。但是假设是一个顶点很多,而边数很少的图,我们需要建立一个v*v大小的图,而大部分的空间都被浪费掉了,如果要进行查找等操作也是及其的不方便,这种图我们称其是稀疏的,显然要存储稀疏图还需要其他的算法。
但是如果是稠密图(边数很多),用这种方式是很方便的。

还是用点的邻接关系来表示图,想到了数组,那很容易就可以想到表了。
直接用链表来动态申请内存不就行了?

这里写图片描述

用链表来存储不仅可以存储边的权值,还可以方便的找出与其邻接的下一个点,如果用单向链表来表示的话,可想起内存的使用量基本上是双倍的,因为一个结点只能指向下一个结点而不能后退。虽然说指针是一个比较难掌握的东西,但是他确是一个很方便的东西,如果我们在这里使用双向链表或者甚至是循环链表,就可以让空间节省很多,但是这对于指针的掌控要求很高。
所以还需要继续努力啊。

创建一个固定的图的邻接表表示
代码

#include<stdio.h>
#include<stdlib.h>

typedef struct GraghNode
{
    int Element;
    struct GraghNode *next;
}Node;

typedef struct Gragh
{
    int EdgeNum = 8;
    Node *TheCells;     
}Gragh;

Gragh CreatedGragh();
void FreeGragh(Gragh G);
void PrintfGragh(Gragh G);
int main()
{
    Gragh G;
    G =  CreatedGragh();
    PrintfGragh(G);
    FreeGragh(G);

}
Gragh CreatedGragh()
{
    Gragh G;
    Node *Temp;
    G.TheCells = (Node*)malloc(sizeof(Node)*G.EdgeNum);
    if(G.TheCells == NULL)
    {
        printf("Out of space!!");
        exit(1);
    }

    //不用第一个Node,将其置为NULL        
    for(int i = 0; i < G.EdgeNum; i++)
    {
        G.TheCells[i].Element = i;
        G.TheCells[i].next = NULL;
    }
    //定义一个固定的图 

    G.TheCells[1].next = (Node*)malloc(sizeof(Node));
    if(Temp == NULL)
    {
        printf("Error!");
        exit(1);
    }
    Temp = G.TheCells[1].next;
    Temp->Element = 2;
    Temp->next = (Node*)malloc(sizeof(Node));
    if(Temp == NULL)
    {
        printf("Error!");
        exit(1);
    }
    Temp = Temp->next;
    Temp->Element = 4;
    Temp->next = (Node*)malloc(sizeof(Node));
    if(Temp == NULL)
    {
        printf("Error!");
        exit(1);
    }
    Temp = Temp->next;
    Temp->Element = 3;
    Temp->next = NULL;



    G.TheCells[2].next = (Node*)malloc(sizeof(Node));
    if(Temp == NULL)
    {
        printf("Error!");
        exit(1);
    }
    Temp = G.TheCells[2].next;
    Temp->Element = 4;
    Temp->next = (Node*)malloc(sizeof(Node));
    if(Temp == NULL)
    {
        printf("Error!");
        exit(1);
    }
    Temp = Temp->next;
    Temp->Element = 5;
    Temp->next = NULL;

    G.TheCells[3].next = (Node*)malloc(sizeof(Node));
    if(Temp == NULL)
    {
        printf("Error!");
        exit(1);
    }
    Temp = G.TheCells[3].next;
    Temp->Element = 6;
    Temp->next = NULL;

    G.TheCells[4].next = (Node*)malloc(sizeof(Node));
    if(Temp == NULL)
    {
        printf("Error!");
        exit(1);
    }
    Temp = G.TheCells[4].next;
    Temp->Element = 6;
    Temp->next = (Node*)malloc(sizeof(Node));
    if(Temp == NULL)
    {
        printf("Error!");
        exit(1);
    }
    Temp = Temp->next;
    Temp->Element = 7;
    Temp->next = (Node*)malloc(sizeof(Node));
    if(Temp == NULL)
    {
        printf("Error!");
        exit(1);
    }
    Temp = Temp->next;
    Temp->Element = 3;
    Temp->next = NULL;

    G.TheCells[5].next = (Node*)malloc(sizeof(Node));
    if(Temp == NULL)
    {
        printf("Error!");
        exit(1);
    }
    Temp = G.TheCells[5].next;
    Temp->Element = 4;
    Temp->next = (Node*)malloc(sizeof(Node));
    if(Temp == NULL)
    {
        printf("Error!");
        exit(1);
    }
    Temp = Temp->next;
    Temp->Element = 7;
    Temp->next = NULL;

    G.TheCells[7].next = (Node*)malloc(sizeof(Node));
    if(Temp == NULL)
    {
        printf("Error!");
        exit(1);
    }
    Temp = G.TheCells[7].next;
    Temp->Element = 6;
    Temp->next = NULL;

    return G;       
}
void PrintfGragh(Gragh G)
{
    int i;
    Node *Temp = NULL;
    for(i = 1; i < G.EdgeNum; i++)
    {
        printf("%-2d| ", G.TheCells[i].Element);   //输出头单元 
        if(G.TheCells[i].next != NULL)
        {
            Temp = G.TheCells[i].next;
            do
            {
                printf("%2d", Temp->Element);
                Temp = Temp->next;
            }while(Temp!=NULL);         
        }
        printf("\n-----------------------------\n");                
    }
}

void FreeGragh(Gragh G)
{
    int i;
    Node *Temp = NULL, *Temp1 = NULL;
    for(i = 0; i < G.EdgeNum; i++)
    {
        if(G.TheCells[i].next != NULL)
        {
            Temp = G.TheCells[i].next;
            do
            {   Temp1 = Temp;
                Temp = Temp->next;          
                free(Temp1);

            }while(Temp!=NULL);         
        }               
    }
    free(G.TheCells);
}

结果

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值