在c中获取距离2图邻接列表中的邻居

在c中获取距离2图邻接列表中的邻居,c,adjacency-list,C,Adjacency List,我用c语言中的邻接列表创建了一个图 问题是,我只想获取并打印距离给定节点2的邻居。我尝试了BFS,但它得到了一个节点可以去的每个节点。我知道如果我使用了邻接矩阵,我可以将矩阵与自身相乘 我使用的代码结构如下所示 // BFS algorithm in C #include <stdio.h> #include <stdlib.h> #define SIZE 40 struct queue { int items[SIZE]; int front; int

我用c语言中的邻接列表创建了一个图 问题是,我只想获取并打印距离给定节点2的邻居。我尝试了BFS,但它得到了一个节点可以去的每个节点。我知道如果我使用了邻接矩阵,我可以将矩阵与自身相乘

我使用的代码结构如下所示

// BFS algorithm in C

#include <stdio.h>
#include <stdlib.h>
#define SIZE 40

struct queue {
  int items[SIZE];
  int front;
  int rear;
};

struct queue* createQueue();
void enqueue(struct queue* q, int);
int dequeue(struct queue* q);
void display(struct queue* q);
int isEmpty(struct queue* q);
void printQueue(struct queue* q);

struct node {
  int vertex;
  struct node* next;
};

struct node* createNode(int);

struct Graph {
  int numVertices;
  struct node** adjLists;
  int* visited;
};

// BFS algorithm
void bfs(struct Graph* graph, int startVertex) {
  struct queue* q = createQueue();

  graph->visited[startVertex] = 1;
  enqueue(q, startVertex);

  while (!isEmpty(q)) {
    printQueue(q);
    int currentVertex = dequeue(q);
    printf("Visited %d\n", currentVertex);

    struct node* temp = graph->adjLists[currentVertex];

    while (temp) {
      int adjVertex = temp->vertex;

      if (graph->visited[adjVertex] == 0) {
        graph->visited[adjVertex] = 1;
        enqueue(q, adjVertex);
      }
      temp = temp->next;
    }
  }
}

// Creating a node
struct node* createNode(int v) {
  struct node* newNode = malloc(sizeof(struct node));
  newNode->vertex = v;
  newNode->next = NULL;
  return newNode;
}

// Creating a graph
struct Graph* createGraph(int vertices) {
  struct Graph* graph = malloc(sizeof(struct Graph));
  graph->numVertices = vertices;

  graph->adjLists = malloc(vertices * sizeof(struct node*));
  graph->visited = malloc(vertices * sizeof(int));

  int i;
  for (i = 0; i < vertices; i++) {
    graph->adjLists[i] = NULL;
    graph->visited[i] = 0;
  }

  return graph;
}

// Add edge
void addEdge(struct Graph* graph, int src, int dest) {
  // Add edge from src to dest
  struct node* newNode = createNode(dest);
  newNode->next = graph->adjLists[src];
  graph->adjLists[src] = newNode;

  // Add edge from dest to src
  newNode = createNode(src);
  newNode->next = graph->adjLists[dest];
  graph->adjLists[dest] = newNode;
}

// Create a queue
struct queue* createQueue() {
  struct queue* q = malloc(sizeof(struct queue));
  q->front = -1;
  q->rear = -1;
  return q;
}

// Check if the queue is empty
int isEmpty(struct queue* q) {
  if (q->rear == -1)
    return 1;
  else
    return 0;
}

// Adding elements into queue
void enqueue(struct queue* q, int value) {
  if (q->rear == SIZE - 1)
    printf("\nQueue is Full!!");
  else {
    if (q->front == -1)
      q->front = 0;
    q->rear++;
    q->items[q->rear] = value;
  }
}

// Removing elements from queue
int dequeue(struct queue* q) {
  int item;
  if (isEmpty(q)) {
    printf("Queue is empty");
    item = -1;
  } else {
    item = q->items[q->front];
    q->front++;
    if (q->front > q->rear) {
      printf("Resetting queue ");
      q->front = q->rear = -1;
    }
  }
  return item;
}

// Print the queue
void printQueue(struct queue* q) {
  int i = q->front;

  if (isEmpty(q)) {
    printf("Queue is empty");
  } else {
    printf("\nQueue contains \n");
    for (i = q->front; i < q->rear + 1; i++) {
      printf("%d ", q->items[i]);
    }
  }
}

int main() {
  struct Graph* graph = createGraph(6);
  addEdge(graph, 0, 1);
  addEdge(graph, 0, 2);
  addEdge(graph, 1, 2);
  addEdge(graph, 1, 4);
  addEdge(graph, 1, 3);
  addEdge(graph, 2, 4);
  addEdge(graph, 3, 4);

  bfs(graph, 0);

  return 0;
}
//C语言中的BFS算法
#包括
#包括
#定义尺寸40
结构队列{
整数项目[大小];
内锋;
内部后部;
};
结构队列*createQueue();
void队列(结构队列*q,int);
int-dequeue(结构队列*q);
无效显示(结构队列*q);
int isEmpty(结构队列*q);
无效打印队列(结构队列*q);
结构节点{
int顶点;
结构节点*下一步;
};
结构节点*createNode(int);
结构图{
智力;
结构节点**调整列表;
国际*访问;
};
//BFS算法
void bfs(结构图*图,int startVertex){
结构队列*q=createQueue();
图形->已访问[startVertex]=1;
排队(q,startVertex);
而(!isEmpty(q)){
打印队列(q);
int currentVertex=出列(q);
printf(“已访问%d\n”,currentVertex);
结构节点*temp=图形->调整列表[currentVertex];
while(临时){
int adjVertex=温度->顶点;
如果(图形->访问[adjVertex]==0){
图形->访问的[adjVertex]=1;
排队(q,顶点);
}
温度=温度->下一步;
}
}
}
//创建节点
结构节点*createNode(int v){
结构节点*newNode=malloc(sizeof(结构节点));
newNode->vertex=v;
newNode->next=NULL;
返回newNode;
}
//创建图形
结构图*createGraph(int顶点){
结构图*Graph=malloc(sizeof(结构图));
图形->numVertices=顶点;
图形->调整列表=malloc(顶点*sizeof(结构节点*);
graph->visited=malloc(顶点*sizeof(int));
int i;
对于(i=0;i<顶点;i++){
图形->调整列表[i]=NULL;
图形->访问[i]=0;
}
返回图;
}
//添加边
void addEdge(结构图*图,int src,int dest){
//将边从src添加到dest
结构节点*newNode=createNode(dest);
新建节点->下一步=图形->调整列表[src];
图形->调整列表[src]=newNode;
//将边缘从dest添加到src
newNode=createNode(src);
新建节点->下一步=图形->调整列表[dest];
图形->调整列表[dest]=newNode;
}
//创建队列
结构队列*createQueue(){
结构队列*q=malloc(sizeof(结构队列));
q->front=-1;
q->rear=-1;
返回q;
}
//检查队列是否为空
int isEmpty(结构队列*q){
如果(q->后==-1)
返回1;
其他的
返回0;
}
//向队列中添加元素
void排队(结构队列*q,int值){
如果(q->后==尺寸-1)
printf(“\n队列已满!!”;
否则{
如果(q->front==-1)
q->front=0;
q->rear++;
q->items[q->rear]=值;
}
}
//从队列中删除元素
int出列(结构队列*q){
国际项目;
if(isEmpty(q)){
printf(“队列为空”);
项目=-1;
}否则{
物料=q->物料[q->前端];
q->front++;
如果(q->前>q->后){
printf(“重置队列”);
q->front=q->rear=-1;
}
}
退货项目;
}
//打印队列
无效打印队列(结构队列*q){
int i=q->前部;
if(isEmpty(q)){
printf(“队列为空”);
}否则{
printf(“\n队列包含\n”);
用于(i=q->前部;i后部+1;i++){
printf(“%d”,q->items[i]);
}
}
}
int main(){
结构图*Graph=createGraph(6);
加法(图,0,1);
加法(图,0,2);
附录(图1,2);
附录(图1,4);
附录(图1,3);
附录(图2,4);
附录(图3、4);
bfs(图,0);
返回0;
}
  • N成为您感兴趣的节点,查找距离

  • 将可直接从N访问的每个元素放入列表/队列

  • 将每个元素标记为不可访问(false)

  • 对于步骤2中添加的每个元素,检查它们的邻接列表,并将可访问的节点标记为可访问(true)

  • 检查哪些节点是可访问的

  • 伪代码:

     queue<nodes> Q = EMPTY
     for each node N reachable from START NODE:
          enqueue N in Q
     array<bool> IS_REACHABLE = FALSE (for all nodes)
     for each node N in Q:
          go through the adjacency list of N and mark TRUE in array iS_REACHABLE for every element reachable from N
          remove N from Q
    
    队列Q=空
    对于从开始节点可到达的每个节点N:
    排队
    array IS_REACHABLE=FALSE(适用于所有节点)
    对于Q中的每个节点N:
    遍历N的邻接列表,并将数组中的TRUE标记为可从N访问的每个元素都可访问
    从Q中去掉N
    

    数组的元素是可到达的,如果是真的,则将是您的答案。

    您需要一个
    距离
    数组来跟踪它

    将起始节点的距离设置为0。每次将新节点排队时,将该节点的距离更新为其父节点的距离+1。打印距离[顶点]==2的节点

    void bfs( ... ) {
      ...
      distance[startVertex] = 0;
      while (!isEmpty(q)) { 
        int currentVertex = dequeue(q);
        ....
        while (temp) {
          ....
          if (graph->visited[adjVertex] == 0) {
            graph->visited[adjVertex] = 1;
            enqueue(q, adjVertex);
            distance[adjVertex] = distance[currentVertex] + 1;
          }
        }
      }
    }
    
    

    您需要使用起始节点的所有相邻节点为队列种子,然后在不向队列添加任何节点的情况下运行BFS。@user3386109我使用我使用的当前BFS算法更新了代码。您可以复制
    while(temp)
    循环,将起始顶点的相邻节点排队。然后运行
    while(!isEmpty(q))
    循环,但是从
    while(temp)
    循环中删除
    enqueue(q,adjVertex)
    调用。那么这是bfs的一个变体?我用当前使用的bfs算法更新了代码是的,该策略与传统的bfs算法相似。你可以用一点“扭曲”来称它为bfs。你能基于上面的bfs函数做一个伪代码吗?我不确定如何使每个元素都不可访问是的,将更新答案我尝试过,但似乎不起作用,我不确定我做错了什么看到了吗above@cstac距离[adjnumber]=距离[adjnumber]+1是错误的。应该是距离[currentnumber]+1。哦,对不起,好的,我更正了。但是我在哪里打印?过一会儿?@user3009403就交给你了。您可以在
    while(!isEmpty(q))
    循环之后执行,也可以在
    dist[]=dist[]之后执行+