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

结构体指针与结构体?


#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日

悬赏问题

  • ¥15 数学的三元一次方程求解
  • ¥20 iqoo11 如何下载安装工程模式
  • ¥15 本题的答案是不是有问题
  • ¥15 关于#r语言#的问题:(svydesign)为什么在一个大的数据集中抽取了一个小数据集
  • ¥15 C++使用Gunplot
  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 蓝桥杯单片机第十三届第一场,整点继电器吸合,5s后断开出现了问题