西皮呦 2022-03-14 18:43 采纳率: 83.3%
浏览 31
已结题

结构体指针与结构体?


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

#include<string.h>

#define MAX 100
#define LENGTH(a) (sizeof(a)/sizeof(a[0]))

//邻接表中标对应的链表的结点
typedef struct _ENode
{
    int ivex;                   // 该边所指向的顶点的位置,是数组的下标
    struct _ENode* next_edge;   // 指向下一条弧的指针
}ENode,*PENode;

//邻接表中的表的顶点
typedef struct _VNode
{
    char data;              // 顶点信息
    ENode* first_edge;      // 指向第一条依附该顶点的弧
}VNode;

//邻接表
typedef struct _LGraph
{
    int vexnum;            // 图的顶点的数目
    int edgnum;            // 图的边的数目
    VNode vexs[MAX];
}LGraph;

//返回ch在matrix矩阵中的位置
static int get_position(LGraph g, char ch)    //为什么用static?
{
    int i;
    for (i = 0; i < g.vexnum; i++)
        if (g.vexs[i].data == ch)
            return i;
    return -1;
}
//将node链接到list的末尾
static void link_last(ENode* list, PENode node)
{
    PENode p = list;
    while (p->next_edge)
        p = p->next_edge;
    p->next_edge = node;
}
//打印邻接表图
void print_lgraph(LGraph G)
{
    int i;
    PENode node;

    printf("List Graph:\n");
    for (i = 0; i < G.vexnum; i++)  //遍历所有的顶点
    {
        printf("%d(%c): ", i, G.vexs[i].data);
        node = G.vexs[i].first_edge;
        while (node != NULL)  //把每个顶点周围的结点都输出一下
        {
            printf("%d(%c) ", node->ivex, G.vexs[node->ivex].data);
            node = node->next_edge;
        }
        printf("\n");
    }
}

//创建邻接表对应的图(用已提供的数据),无向图
LGraph* create_example_lgraph()
{
    char c1, c2;
    char vexs[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
    char edges[][2] = {
        {'A', 'C'},
        {'A', 'D'},
        {'A', 'F'},
        {'B', 'C'},
        {'C', 'D'},
        {'E', 'G'},
        {'F', 'G'} };
    int vlen = LENGTH(vexs);
    int elen = LENGTH(edges);
    //上面类似一个邻接矩阵存储
    int pos1, pos2;
    ENode* node1, * node2;      //无向图,一条边两个对应关系
    LGraph* pG;                 //pG表示图

    if ((pG = (LGraph*)malloc(sizeof(_LGraph))) == NULL)   ///////
        //若硬件没有内存申请失败
        return NULL;
    memset(pG, 0, sizeof(LGraph));//就是把申请的空间内初始化为0

    // 初始化"顶点数"和"边数"
    pG->vexnum = vlen;
    pG->edgnum = elen;
    // 初始化"邻接表"的顶点
    for (int i = 0; i < pG->edgnum; i++)
    {
        pG->vexs[i].data = vexs[i];
        pG->vexs[i].first_edge = NULL;
    }

    // 初始化"邻接表"的边
    for (int i = 0; i < pG->edgnum; i++)
    {
        // 读取边的起始顶点和结束顶点
        c1 = edges[i][0];
        c2 = edges[i][1];

        pos1 = get_position(*pG, c1);        //pos1对应起始顶点下标位置
        pos2 = get_position(*pG, c2);        //pos2对应结束顶点下标位置
                                             //这里传入用结构体而不是结构体指针,因为没有对其本身改变后续更改的时候因为成员是数组可以
        // 初始化node1
        node1 = (ENode*)calloc(1, sizeof(ENode));
        node1->ivex = pos2;
        // 将node1链接到"p1所在链表的末尾"
        if (pG->vexs[pos1].first_edge == NULL)
            pG->vexs[pos1].first_edge = node1;
        else
            link_last(pG->vexs[pos1].first_edge, node1);
       
        // 初始化node2
        node2 = (ENode*)calloc(1, sizeof(ENode));
        node2->ivex = pos1;
        // 将node2链接到"p2所在链表的末尾"
        if (pG->vexs[pos2].first_edge == NULL)
            pG->vexs[pos2].first_edge = node2;
        else
            link_last(pG->vexs[pos2].first_edge, node2);
    }
}

//创建邻接表对应的图(用已提供的数据),有向图
LGraph* create_example_lgraph_directed()
{
    char c1, c2;
    char vexs[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
    char edges[][2] = {
        {'A', 'C'},
        {'A', 'D'},
        {'A', 'F'},
        {'B', 'C'},
        {'C', 'D'},
        {'E', 'G'},
        {'F', 'G'} };
    int vlen = LENGTH(vexs);
    int elen = LENGTH(edges);
    //上面类似一个邻接矩阵存储
    int pos1, pos2;
    ENode* node1, * node2;      //无向图,一条边两个对应关系
    LGraph* pG;                 //pG表示图

    if ((pG = (LGraph*)malloc(sizeof(_LGraph))) == NULL)   ///////
        //若硬件没有内存申请失败
        return NULL;
    memset(pG, 0, sizeof(LGraph));//就是把申请的空间内初始化为0

    // 初始化"顶点数"和"边数"
    pG->vexnum = vlen;
    pG->edgnum = elen;
    // 初始化"邻接表"的顶点
    for (int i = 0; i < pG->edgnum; i++)
    {
        pG->vexs[i].data = vexs[i];
        pG->vexs[i].first_edge = NULL;
    }

    // 初始化"邻接表"的边
    for (int i = 0; i < pG->edgnum; i++)
    {
        // 读取边的起始顶点和结束顶点
        c1 = edges[i][0];
        c2 = edges[i][1];

        pos1 = get_position(*pG, c1);        //pos1对应起始顶点下标位置
        pos2 = get_position(*pG, c2);        //pos2对应结束顶点下标位置
                                             //这里传入用结构体而不是结构体指针,因为没有对其本身改变后续更改的时候因为成员是数组可以
        // 初始化node1
        node1 = (ENode*)calloc(1, sizeof(ENode));
        node1->ivex = pos2;
        // 将node1链接到"p1所在链表的末尾"
        if (pG->vexs[pos1].first_edge == NULL)
            pG->vexs[pos1].first_edge = node1;
        else
            link_last(pG->vexs[pos1].first_edge, node1);
    }
}

//深度优先搜索遍历图的递归实现
static void DFS(LGraph G, int i, int visited[])
{
    printf("%c ", G.vexs[i].data);
    visited[i] = 1;
    ENode* node;
    node = G.vexs[i].first_edge;
    while (node !=NULL)
    {
        if (!visited[node->ivex])//只要对应顶点没有访问过,深入到下一个顶点访问
            DFS(G, node->ivex, visited);
        node = node->next_edge;//某个顶点的下一条边,例如B结点的下一条边
    }
}

//深度优先搜索遍历图
void DFSTraverse(LGraph G)
{
    int visited[MAX];       // 顶点访问标记
    //初始化所有顶点都没有被访问
    memset(visited, 0, sizeof(visited));
   /* for (int i = 0; i < G.vexnum; i++)
        visited[i] = 0;*/
    printf("DFS:");
    for (int i = 0; i < G.vexnum; i++)
    {
        if (!visited[i])
            DFS(G, i, visited);
    }
    printf("\n");
}

int main()
{
    LGraph* pG;
    pG = create_example_lgraph_directed();
    print_lgraph(*pG);
    DFSTraverse(*pG);
}

请问定义函数时 比如static void DFS(LGraph G, int i, int visited[])
为什么用LGraph呢 是不是把结构体指针当做参数传入也可以呀 就是后面的访问要变成-> 了

  • 写回答

1条回答 默认 最新

  • 快乐鹦鹉 2022-03-14 19:35
    关注

    你说的是可以的

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 3月22日
  • 已采纳回答 3月14日
  • 创建了问题 3月14日

悬赏问题

  • ¥50 adb连接不到手机是怎么回事?
  • ¥15 vs2022无法联网
  • ¥15 TCP的客户端和服务器的互联
  • ¥15 VB.NET操作免驱摄像头
  • ¥15 笔记本上移动热点开关状态查询
  • ¥85 类鸟群Boids——仿真鸟群避障的相关问题
  • ¥15 CFEDEM自带算例错误,如何解决?
  • ¥15 有没有会使用flac3d软件的家人
  • ¥20 360摄像头无法解绑使用,请教解绑当前账号绑定问题,
  • ¥15 docker实践项目