C 从图形开始

C 从图形开始,c,C,我知道这听起来很幼稚,但有人能告诉我如何用C语言实现图形吗。我已经读过这个理论,但我无法用图形编程摆脱障碍 如果有人能解释一下如何使用邻接列表和邻接矩阵创建一个图,以及如何在C代码中执行广度优先搜索和深度优先搜索,我将不胜感激 在此之前,我想告诉你,这不是家庭作业。我真的很想学图形,但请不起家教。我假设这里的图形是顶点和边的集合。为此,您需要一个指向结构的指针数组。这是图的邻接列表表示法。这些结构至少有一个值,即节点号和指向另一个结构的指针。在向图形插入新节点时,只需转到数组的适当索引,并在

我知道这听起来很幼稚,但有人能告诉我如何用C语言实现图形吗。我已经读过这个理论,但我无法用图形编程摆脱障碍


如果有人能解释一下如何使用邻接列表和邻接矩阵创建一个图,以及如何在C代码中执行广度优先搜索和深度优先搜索,我将不胜感激



在此之前,我想告诉你,这不是家庭作业。我真的很想学图形,但请不起家教。

我假设这里的图形是顶点和边的集合。为此,您需要一个指向结构的指针数组。这是图的邻接列表表示法。这些结构至少有一个值,即节点号和指向另一个结构的指针。在向图形插入新节点时,只需转到数组的适当索引,并在开始处推送节点。这是插入的O(1)时间。我的实现可能会帮助您了解它的实际工作原理。如果您在C语言方面有很好的技能,那么理解代码不会花费太多时间

//  Graph implementation by adjacency list

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

#define MAX_SIZE 1000

typedef struct node{
    int number;
    struct node * next;
} Node;


//  U is starting node, V is ending node
void addNode (Node *G[], int U, int V, int is_directed)
{
    Node * newnode = (Node *)malloc(sizeof(Node));
    newnode->number = V;
    newnode->next = G[U];
    G[U] = newnode;

//  0 for directed, 1 for undirected
    if (is_directed)
    {
        Node * newnode = (Node *)malloc(sizeof(Node));
        newnode->number = U;
        newnode->next = G[V];
        G[V] = newnode;
    }
}

void printgraph(Node *G[], int num_nodes)
{
    int I;
    for (I=0; I<=num_nodes; I++)
    {
        Node *dum = G[I];
        printf("%d : ",I);
        while (dum != NULL)
        {
            printf("%d, ",dum->number);
            dum =dum->next;
        }
        printf("\n");
    }

}



void dfs (Node *G[], int num_nodes, int start_node)
{
    int stack[MAX_SIZE];
    int color[num_nodes+1];
    memset (color, 0, sizeof(color));
    int top = -1;
    stack[top+1] = start_node;
    top++;
    while (top != -1)
    {
        int current = stack[top];
        printf("%d  ",current);
        top--;
        Node *tmp = G[current];
        while (tmp != NULL)
        {
            if (color[tmp->number] == 0)
            {
                stack[top+1] = tmp->number;
                top++;
                color[tmp->number] = 1;
            }
            tmp = tmp->next;
        }
    }

}

void bfs (Node *G[], int num_nodes, int start_node)
{
    int queue[MAX_SIZE];
    int color[num_nodes+1];
    memset (color, 0, sizeof (color));
    int front=-1, rear=-1;
    queue[rear+1] = start_node;
    rear++;printf("\n\n");
    while (front != rear)
    {
        front++;
        int current = queue[front];
        printf("%d  ",current);

        Node *tmp = G[current];
        while (tmp != NULL)
        {
            if (color[tmp->number] == 0)
            {
                queue[rear+1] = tmp->number;
                rear++;
                color[tmp->number] = 1;
            }
            tmp = tmp->next;
        }
    }

}  

int main(int argc, char **argv)
{
    int num_nodes;
    // For Demo take num_nodes = 4
    scanf("%d",&num_nodes);
    Node *G[num_nodes+1];
    int I;
    for (I=0; I<num_nodes+1 ;I++ )
        G[I] = NULL;

    addNode (G, 0, 2, 0);
    addNode (G, 0, 1, 0);
    addNode (G, 1, 3, 0);
    addNode (G, 2, 4, 0);
    addNode (G, 2, 1, 0);
    printgraph( G, num_nodes);
    printf("DFS on graph\n");
    dfs(G, num_nodes, 0);
    printf("\n\nBFS on graph\n");
    bfs(G, num_nodes, 0);

    return 0;
} 
//通过邻接列表实现图形
#包括
#包括
#包括
#定义最大尺寸1000
类型定义结构节点{
整数;
结构节点*下一步;
}节点;
//U是起始节点,V是结束节点
void addNode(节点*G[],int U,int V,int是有向的)
{
Node*newnode=(Node*)malloc(sizeof(Node));
newnode->number=V;
newnode->next=G[U];
G[U]=新节点;
//0表示有向,1表示无向
如果(是否有指示)
{
Node*newnode=(Node*)malloc(sizeof(Node));
新建节点->编号=U;
newnode->next=G[V];
G[V]=newnode;
}
}
void printgraph(节点*G[],int num_节点)
{
int I;
对于(I=0;数量);
dum=dum->next;
}
printf(“\n”);
}
}
无效dfs(节点*G[],整数个节点,整数个开始节点)
{
int堆栈[MAX_SIZE];
int color[num_节点+1];
memset(颜色,0,sizeof(颜色));
int top=-1;
堆栈[top+1]=开始节点;
top++;
while(顶部!=-1)
{
int current=堆栈[顶部];
printf(“%d”,当前);
顶部--;
节点*tmp=G[当前];
while(tmp!=NULL)
{
如果(颜色[tmp->编号]==0)
{
堆栈[top+1]=tmp->number;
top++;
颜色[tmp->编号]=1;
}
tmp=tmp->next;
}
}
}
void bfs(节点*G[],int num_节点,int start_节点)
{
int队列[MAX_SIZE];
int color[num_节点+1];
memset(颜色,0,sizeof(颜色));
前内=-1,后=-1;
队列[rear+1]=开始节点;
rear++;printf(“\n\n”);
while(前面!=后面)
{
前端++;
int current=队列[前端];
printf(“%d”,当前);
节点*tmp=G[当前];
while(tmp!=NULL)
{
如果(颜色[tmp->编号]==0)
{
队列[后方+1]=tmp->编号;
后++;
颜色[tmp->编号]=1;
}
tmp=tmp->next;
}
}
}  
int main(int argc,字符**argv)
{
int num_节点;
//对于演示,取num_节点=4
scanf(“%d”、&num_节点);
节点*G[num_节点+1];
int I;

对于(I=0;I好吧,一个真正简单而基本的答案是,可以使用包含指向其他此类数据结构的指针的数据结构用C表示图形。图形实际上只是双链接列表,可以从一个节点具有多个链接。如果您还没有消化链表和双链接列表,那将是一个好地方o开始

假设你有一个邻接列表,{a,b},{b,c},{d},{b,e}。首先,你解析它并列出你所有的唯一项。(一个常规的链表,数组,不管什么,它只是一个临时结构来帮助你。你可以绕过它,动态地做,可能会获得一个加速,但这很简单。)遍历该列表时,您将为每个项目生成一个节点。对于每个节点,您将再次遍历邻接列表,并在它看到自己时创建一条边。这是节点内指向另一个节点的指针

最后,你有一个所有节点的常规列表,这样你就不会丢失单独挂在外面的“d”节点。你还有一个所有节点的图表,这样你就知道它们之间的关系

搜索
在图中搜索是一个非常基本的想法。从一个节点开始,比较,移动到它的一个邻居,然后再做一次。但是有很多陷阱。比如进入一个无休止的循环,知道什么时候停止


如果你想得到比你在网上已经能找到的更好的解释,你必须问更具体的问题。

谷歌的第一个结果:如果你想学习,互联网上有100个网站(包括非常好的网站)它免费详细描述了图形表示和算法。那么,如果它们不是你想要的,或者不是C语言呢?这就是问题所在。我无法理解。你能解释一下我如何创建一个图形,然后我会自己尝试吗?我刚刚试过你的代码,它工作得很好,但你不认为你应该uld对顶点节点和边节点有单独的结构。类似于这样的结构图节点{int data;结构节点*adjList[MAX];};结构节点{int nodenumber;结构节点*node;};@CSS:是的,可能是,但对于大多数目的来说,这种简单的方法工作得很好。