繁体   English   中英

从文件中读取整数(C语言),其中包括有向图的数据

[英]reading integers from a file (in C) which including data of a directed graph

假设我创建了一个名为graph-file.txt的文件,其中包含

有向图如下:

7
{5, 2, 3}, {1,5}, {}, { }, {3}, { }, { }

文件的第一行显示了顶点数(在这种情况下为7)。 第二行描述每个顶点的邻居N +(v)。 例如,从第1个顶点开始,边被指向顶点5,2和3,而对于第7个顶点,没有边指向该图中的任何其他顶点。

我想问一下从该文件读取有关边的信息(如上所述)的方法,BFS算法需要哪些信息?

我对BFS使用以下功能:

#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;
};

struct Graph* createGraph(int vertices);
void addEdge(struct Graph* graph, int src, int dest);
void printGraph(struct Graph* graph);
void bfs(struct Graph* graph, int startVertex);


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;
       }
    }
}


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


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;
}

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;
}

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


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

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;
    }
}

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;
}

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]);
        }
    }    
}

假设输入是有效的,作为一个有趣的练习,我尝试提出所需的最小解析器。 对于x86_64,它使用少量寄存器将其编译为少于40条指令

void edge(int from, int to);

void parse(void)
{
    int v = 0;
    for (;;) {
        const int c = getchar();
        if (c == EOF)
            return;

        // Next 'from' vertex?
        if (c == '{') {
            ++v;
            continue;
        }

        // Ignore vertex count
        if (v == 0)
            continue;

        // Found 'to' vertex?
        int w = c - '0';
        if (w < 0 || w > 9)
            continue;

        // Parse 'to' vertex
        for (;;) {
            const int d = getchar() - '0';
            if (d < 0 || d > 9)
                break;
            w = w * 10 + d;
        }

        edge(v, w);
    }
}

当然,如果需要验证输入,则将需要更多状态来处理逗号,右括号,顶点数量不匹配,超出范围的顶点数量,无效字符等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM