微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何去除未加权图中两个节点之间的边 - C 程序

如何解决如何去除未加权图中两个节点之间的边 - C 程序

当我用 Dijkstra 的算法挑战我的技能并制作一个社交网络范式时,一个人最多可以有 500 个朋友。

在我的代码中有三个函数

  • AddFriendship(在好友节点之间建立一个边)
  • WantToBeFriend(使用 Dijkstra 算法通过最短路径推荐好友)
  • RemoveFriendship(删除好友节点之间的边)

在广泛研究和开发的帮助下,我实现了 Dijkstra 算法。通过调用 AddFriendship 函数,我可以简单地添加节点及其边(权重始终为 1)。使用最短路线并通过调用 WantToBeFriend 函数,好友建议也能完美运行。

但我无法实现 RemoveFriendship 功能。此函数的目的是简单地删除两个节点(朋友)之间的边。如果两个用户不是朋友,那么它应该打印一个错误No Friendship”。

到目前为止,这是我的代码工作:

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

#define NAME_LENGTH 20
#define FRIENDS 500

typedef struct {
    int vertex;
    int weight;
} edge_t;

typedef struct {
    edge_t **edges;
    int edges_len;
    int edges_size;
    int dist;
    int prev;
    int visited;
} vertex_t;

typedef struct {
    vertex_t **vertices;
    int vertices_len;
    int vertices_size;
} graph_t;

typedef struct {
    int *data;
    int *prio;
    int *index;
    int len;
    int size;
} heap_t;

struct DList{
    char name[NAME_LENGTH + 1];
    int id;
    int friends[FRIENDS];
    struct DList *next;
};
struct DList *head = NULL;

int SIZE = -1;



int addindList(char *name){
    struct DList *new_data = (struct DList*) malloc(sizeof(struct DList));
    SIZE++;
    new_data->id = SIZE;
    strcpy(new_data->name,name);
    int i=0;
    for(i; i<FRIENDS; i++){
        new_data->friends[i] = -1;
    }
    new_data->next = NULL;
    if(head == NULL){
        head = new_data;
        return new_data->id;
    }else{
        struct DList *ptr = head;
        while(ptr->next != NULL){
            ptr = ptr->next;
        }
        ptr->next = new_data;
        return new_data->id;
    }
}

int searchInDList(char *name){
    if (head == NULL) return 0;
    struct DList *ptr = head;
    while(ptr != NULL){
        if(strcmp(ptr->name,name) == 0)
            return 1;
        else
            ptr = ptr->next;
    }
    return 0;
}

int getDListID(char *name){
    if (head == NULL) return 0;
    struct DList *ptr = head;
    while(ptr != NULL){
        if(strcmp(ptr->name,name) == 0)
            return ptr->id;
        else
            ptr = ptr->next;
    }
    return -1;  
}

char* getDListName(int id){
    if (head == NULL) return 0;
    struct DList *ptr = head;
    while(ptr != NULL){
        if(ptr->id == id)
            return ptr->name;
        else
            ptr = ptr->next;
    }       
}

struct DList *get(int id){
    if (head == NULL) return 0;
    struct DList *ptr = head;
    while(ptr != NULL){
        if(ptr->id == id)
            return ptr;
        else
            ptr = ptr->next;
    }   
}

void printDList(){
    if(head == NULL) return;
    struct DList *ptr = head;
    while(ptr != NULL){
        printf("%s: %d\n",ptr->name,ptr->id);
        ptr = ptr->next;
    }
}

void add_vertex(graph_t *g,int i) {
    if (g->vertices_size < i + 1) {
        int size = g->vertices_size * 2 > i ? g->vertices_size * 2 : i + 4;
        g->vertices = realloc(g->vertices,size * sizeof (vertex_t *));
        int j;
        for (j = g->vertices_size; j < size; j++)
            g->vertices[j] = NULL;
        g->vertices_size = size;
    }
    if (!g->vertices[i]) {
        g->vertices[i] = calloc(1,sizeof (vertex_t));
        g->vertices_len++;
    }
}

int add_edge(graph_t *g,char *val1,char *val2,int a,int b) {
    int w=1;
    struct DList *ptr = get(a);
    int i=0;
    int check = 1;
    for(i=0; i<FRIENDS; i++){
        if(ptr->friends[i] == b){
            check = 0;
            return check;   // Failed to add
        }
    }
    i = 0;
    while(ptr->friends[i] != -1){
        i++;
    }
    if(ptr->friends[i] == -1)
        ptr->friends[i] = b;
    add_vertex(g,a);
    add_vertex(g,b);
    vertex_t *v = g->vertices[a];
    if (v->edges_len >= v->edges_size) {
        v->edges_size = v->edges_size ? v->edges_size * 2 : 4;
        v->edges = realloc(v->edges,v->edges_size * sizeof (edge_t *));
    }
    edge_t *e = calloc(1,sizeof (edge_t));
    e->vertex = b;
    e->weight = w;
    v->edges[v->edges_len++] = e;
    return 1;   // success
}

heap_t *create_heap(int n) {
    heap_t *h = calloc(1,sizeof (heap_t));
    h->data = calloc(n + 1,sizeof (int));
    h->prio = calloc(n + 1,sizeof (int));
    h->index = calloc(n,sizeof (int));
    return h;
}

void push_heap(heap_t *h,int v,int p) {
    int i = h->index[v] == 0 ? ++h->len : h->index[v];
    int j = i / 2;
    while (i > 1) {
        if (h->prio[j] < p)
            break;
        h->data[i] = h->data[j];
        h->prio[i] = h->prio[j];
        h->index[h->data[i]] = i;
        i = j;
        j = j / 2;
    }
    h->data[i] = v;
    h->prio[i] = p;
    h->index[v] = i;
}

int min(heap_t *h,int i,int j,int k) {
    int m = i;
    if (j <= h->len && h->prio[j] < h->prio[m])
        m = j;
   if (k <= h->len && h->prio[k] < h->prio[m])
        m = k;
    return m;
}

int pop_heap (heap_t *h) {
    int v = h->data[1];
    int i = 1;
    while (1) {
        int j = min(h,h->len,2 * i,2 * i + 1);
        if (j == h->len)
            break;
        h->data[i] = h->data[j];
        h->prio[i] = h->prio[j];
        h->index[h->data[i]] = i;
        i = j;
    }
    h->data[i] = h->data[h->len];
    h->prio[i] = h->prio[h->len];
    h->index[h->data[i]] = i;
    h->len--;
    return v;
}

void Dijkstra(graph_t *g,char* val1,char* val2) {
    int a,b,i,j;
    a = getDListID(val1);
    b = getDListID(val2);
    if (a == -1 || b == -1){
        printf("Wrong Arguments\n");
    }
    for (i = 0; i < g->vertices_len; i++) {
        vertex_t *v = g->vertices[i];
        v->dist = INT_MAX;
        v->prev = 0;
        v->visited = 0;
    }
    vertex_t *v = g->vertices[a];
    v->dist = 0;
    heap_t *h = create_heap(g->vertices_len);
    push_heap(h,a,v->dist);
    while (h->len) {
        i = pop_heap(h);
        if (i == b)
            break;
        v = g->vertices[i];
        v->visited = 1;
        for (j = 0; j < v->edges_len; j++) {
            edge_t *e = v->edges[j];
            vertex_t *u = g->vertices[e->vertex];
            if (!u->visited && v->dist + e->weight <= u->dist) {
                u->prev = i;
                u->dist = v->dist + e->weight;
                push_heap(h,e->vertex,u->dist);
            }
        }
    }
}


void ShortestPath(graph_t *g,char* val1) {
    int i,n,j;
    vertex_t *v,*u;
    i = getDListID(val1);
    v = g->vertices[i];
    if (v->dist == INT_MAX) {
        printf("\nSorry,none of Your friends can help introduce you to %s\n",val1);
        return;
    }
    for (n = 1,u = v; u->dist; u = g->vertices[u->prev],n++)
    ;
    int *path = calloc(n,sizeof(int));
    for (j = 0,j++){
        path[n - j - 2] = u->prev;
    }
    path[n - 1] = i;
    if (v->dist>1){
        printf("\n- Length of the shortest path: %d\n",v->dist);
        if (v->dist == 2)
            printf("- Your mutual friend is %s\n",getDListName(path[1]));
        else if(v->dist > 2){
            printf("- Your intermediate friend is %s\n",getDListName(path[1]));
        }
        printf("- Path: ");
        int loop = 0;
        for(loop; loop <= n -1 ; loop++){
            printf("%s ",getDListName(path[loop]));
        }
        printf("\n");   
    } else if (v->dist == 1){
        printf("AlreadyAFriendError\n");
    }
    free(path);
}

void WantToBeFriend(graph_t *g,char* command,char* friend1,char* friend2){
    printf("%s %s %s ",command,friend1,friend2);
    Dijkstra(g,friend2);
    ShortestPath(g,friend2);
}

void AddFriendship(graph_t *g,char* friend2){
    int add_check;
    printf("%s %s %s ",friend2);
    int a,b;
    if (searchInDList(friend1) == 0){
        a = addindList(friend1);
    } else {
        a = getDListID(friend1);
    }
    if (searchInDList(friend2) == 0){
        b = addindList(friend2);
    } else {
        b = getDListID(friend2);
    }
    add_check = add_edge(g,friend2,b);
    if (add_check == 0) {
        printf("ExistingFriendshipError\n");
        return;
    }
    add_check = add_edge(g,a);
    if (add_check == 0){
        printf("ExistingFriendshipError\n");
        return;     
    }
    printf("\n");
}

void RemoveFriendship(graph_t *g,char* friend2){
    /*


        I am struggling here...


    */
}

int main () {
    graph_t *g = calloc(1,sizeof (graph_t));
    AddFriendship(g,"AddFriendship","Alice","Bob"); 
    AddFriendship(g,"Bob","Carol");
    AddFriendship(g,"Carol","Alice");
    AddFriendship(g,"David","Emily");
    AddFriendship(g,"Emily","Frank");
    AddFriendship(g,"Frank","George");
    AddFriendship(g,"George","David");

    AddFriendship(g,"George");
    RemoveFriendship(g,"RemoveFriendship","David");
    WantToBeFriend(g,"WantToBeFriend","Frank");

    return 0;
}

最初我从这个参考资料中获取代码

https://rosettacode.org/wiki/Dijkstra%27s_algorithm#C

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。