如何解决如何去除未加权图中两个节点之间的边 - C 程序
当我用 Dijkstra 的算法挑战我的技能并制作一个社交网络范式时,一个人最多可以有 500 个朋友。
在广泛研究和开发的帮助下,我实现了 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 举报,一经查实,本站将立刻删除。