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

时间:2018-05-26 10:27:28

标签: c file 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]);
        }
    }    
}

1 个答案:

答案 0 :(得分:0)

假设输入有效,作为一个有趣的练习,我试图想出所需的最小解析器。对于x86_64,它使用少量寄存器编译为less than 40 instructions

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

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