Advertisement
andruhovski

prog-0219

Nov 5th, 2014
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.23 KB | None | 0 0
  1. // graph_demo_c.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5. typedef struct vertex VERTEX;
  6. typedef struct vertex_node VERTEX_NODE;
  7. typedef struct vertex_list VERTEX_LIST;
  8.  
  9. typedef struct edge EDGE;
  10. typedef struct edge_node EDGE_NODE;
  11. typedef struct edge_list EDGE_LIST;
  12. typedef struct graph GRAPH;
  13.  
  14. struct vertex {
  15.     char *vertex_name;  //назва
  16.     bool visited;       //індикатор відвідування
  17.     VERTEX_LIST *neighbours; //список сусідів
  18. };
  19.  
  20. struct vertex_node {
  21.     VERTEX *value;   // дані
  22.     VERTEX_NODE *prev;   // поле зв'зку
  23.     VERTEX_NODE *next;   // поле зв'зку
  24. };
  25.  
  26. struct vertex_list {
  27.     struct vertex_node *head;   // поле зв'зку
  28.     struct vertex_node *tail;   // поле зв'зку
  29. };
  30.  
  31. struct edge {
  32.     VERTEX* vertFrom;
  33.     VERTEX* vertTo;
  34. };
  35.  
  36. struct edge_node {
  37.     EDGE value;   // дані
  38.     EDGE_NODE *prev;   // поле зв'зку
  39.     EDGE_NODE *next;   // поле зв'зку
  40. };
  41.  
  42. struct edge_list {
  43.     EDGE_NODE *head;
  44.     EDGE_NODE *tail;
  45. };
  46.  
  47.  
  48. struct graph {
  49.     VERTEX_LIST vertex_list;
  50.     EDGE_LIST edge_list;
  51.     unsigned count;
  52. };
  53.  
  54. VERTEX_NODE *makeVertexNode(VERTEX *v);
  55. EDGE_NODE* makeEdgeNode(EDGE *e);
  56. void initGraph(GRAPH *g);
  57.  
  58. void addVertex(GRAPH *g, VERTEX *v);
  59. void removeVertex(GRAPH *g, VERTEX *v);
  60.  
  61. bool addEdge(GRAPH *g, EDGE *e);
  62. void removeEdge(GRAPH *g, EDGE *e);
  63. void removeEdgeV(GRAPH *g, VERTEX *from, VERTEX *to);
  64.  
  65. void addNeighbour(VERTEX *v, VERTEX *n);
  66. void removeNeibour(VERTEX_NODE *node, VERTEX *key);
  67.  
  68. bool isConnected(VERTEX *v, VERTEX *n);
  69. VERTEX_NODE *findVertex(VERTEX_LIST *vl, VERTEX *key);
  70. void printGraph(GRAPH *g);
  71. bool BFS_traversal(GRAPH *g, VERTEX *start, VERTEX *goal);
  72. bool DFS_traversal(GRAPH *g, VERTEX *start, VERTEX *goal);
  73. void q_push(VERTEX_LIST *q, VERTEX_NODE *value);
  74.  
  75. int _tmain(int argc, _TCHAR* argv[])
  76. {
  77.     GRAPH g;
  78.     VERTEX v[] = { { "0", NULL }, { "1", NULL }, { "2", NULL }, { "3", NULL },
  79.                    { "4", NULL }, { "5", NULL }, { "6", NULL }, { "7", NULL } };
  80.     EDGE edge[] = { { &v[0], &v[2] },
  81.                     { &v[0], &v[5] },
  82.                     { &v[0], &v[7] },
  83.                     { &v[1], &v[7] },
  84.                     { &v[2], &v[6] },
  85.                     { &v[3], &v[4] },
  86.                     { &v[3], &v[5] },
  87.                     { &v[4], &v[6] },
  88.                     { &v[4], &v[7] }};
  89.    
  90.     initGraph(&g);
  91.     for (size_t i = 0; i < 8; i++) addVertex(&g, &v[i]);
  92.     for (size_t i = 0; i < 9; i++) addEdge(&g, &edge[i]);
  93.  
  94.     //printGraph(&g);
  95.     //removeEdge(&g, &edge);
  96.  
  97.     puts("----------");
  98.     printGraph(&g);
  99.     if (BFS_traversal(&g, &v[0], &v[3]))
  100.         puts("Yes!");
  101.     else
  102.         puts("No!");
  103.  
  104.     if (DFS_traversal(&g, &v[0], &v[3]))
  105.         puts("Yes!");
  106.     else
  107.         puts("No!");
  108.     return 0;
  109. }
  110.  
  111.  
  112. VERTEX_NODE *makeVertexNode(VERTEX *v)
  113. {
  114.     VERTEX_NODE *tmp = (VERTEX_NODE *)calloc(1, sizeof(VERTEX_NODE));
  115.     tmp->value = v;
  116.     return tmp;
  117. }
  118.  
  119. EDGE_NODE* makeEdgeNode(EDGE *e)
  120. {
  121.     EDGE_NODE *tmp = (EDGE_NODE *)calloc(1, sizeof(EDGE_NODE));
  122.     tmp->value = *e;
  123.     return tmp;
  124. }
  125.  
  126. void initGraph(GRAPH *g)
  127. {
  128.     g->vertex_list.head = g->vertex_list.tail = NULL;
  129.     g->edge_list.head = g->edge_list.tail = NULL;
  130.     g->count = 0;
  131. }
  132.  
  133. void addVertex(GRAPH *g, VERTEX *v)
  134. {
  135.     VERTEX_NODE *vn = makeVertexNode(v);
  136.     if (g->vertex_list.head == NULL){
  137.         g->vertex_list.head = g->vertex_list.tail = vn;
  138.     }
  139.     else
  140.     {
  141.         g->vertex_list.tail->next = vn;
  142.         vn->prev = g->vertex_list.tail;
  143.         g->vertex_list.tail = vn;
  144.     }
  145.     g->count++;
  146. }
  147.  
  148. bool addEdge(GRAPH *g, EDGE *e)
  149. {
  150.     VERTEX_NODE *vFrom, *vTo;
  151.     if ((vFrom = findVertex(&g->vertex_list, e->vertFrom)) == NULL)
  152.         return false;
  153.     if ((vTo = findVertex(&g->vertex_list, e->vertTo)) == NULL)
  154.         return false;
  155.  
  156.     if (isConnected(e->vertFrom, e->vertTo))
  157.         return false;
  158.  
  159.     EDGE_NODE *en = makeEdgeNode(e);
  160.     if (g->edge_list.head == NULL){
  161.         g->edge_list.head = g->edge_list.tail = en;
  162.     }
  163.     else
  164.     {
  165.         g->edge_list.tail->next = en;
  166.         en->prev = g->edge_list.tail;
  167.         g->edge_list.tail = en;
  168.     }
  169.  
  170.     addNeighbour(e->vertFrom, e->vertTo);
  171.     addNeighbour(e->vertTo, e->vertFrom);
  172.     return true;
  173. }
  174.  
  175. VERTEX_NODE *findVertex(VERTEX_LIST *vl, VERTEX *key)
  176. {
  177.     VERTEX_NODE *temp;
  178.     for (temp = vl->head; temp != NULL; temp = temp->next)
  179.         if (strcmp(temp->value->vertex_name, key->vertex_name) == 0)
  180.             break;
  181.     return temp;
  182. }
  183.  
  184. void addNeighbour(VERTEX *v, VERTEX *n)
  185. {
  186.     VERTEX_LIST *vl = v->neighbours;
  187.     VERTEX_NODE *vn = makeVertexNode(n);
  188.     if (vl == NULL){
  189.         v->neighbours = (VERTEX_LIST*)calloc(1, sizeof(VERTEX_LIST));
  190.         v->neighbours->head = v->neighbours->tail = vn;
  191.     }
  192.     else {
  193.         vl->tail->next = vn;
  194.         vn->prev = vl->tail;
  195.         vl->tail = vn;
  196.     }
  197. }
  198.  
  199. void printGraph(GRAPH *g)
  200. {
  201.     puts("----------");
  202.     for (VERTEX_NODE* temp = g->vertex_list.head; temp != NULL; temp = temp->next)
  203.     {
  204.         if ((temp->value->neighbours!=NULL) && (temp->value->neighbours->head!=NULL))
  205.         {
  206.             printf("%s connected", temp->value->vertex_name);
  207.             for (VERTEX_NODE* temp1 = temp->value->neighbours->head; temp1 != NULL; temp1 = temp1->next)
  208.                 printf("\t%s", temp1->value->vertex_name);
  209.             putchar('\n');
  210.         }
  211.         else
  212.             printf("%s not connected\n", temp->value->vertex_name);
  213.  
  214.     }
  215. }
  216.  
  217. bool isConnected(VERTEX *v, VERTEX *n)
  218. {
  219.     VERTEX_LIST *vl = v->neighbours;
  220.     if (vl == NULL) return false;
  221.     for (VERTEX_NODE *temp = vl->head; temp != NULL; temp = temp->next)
  222.     {
  223.         if (temp->value == n) return true;
  224.     }
  225.     return false;
  226. }
  227.  
  228. bool BFS_traversal(GRAPH *g, VERTEX *start, VERTEX *goal){
  229.     for (VERTEX_NODE *temp = g->vertex_list.head; temp != NULL;
  230.         temp = temp->next)
  231.         temp->value->visited = false;
  232.     VERTEX_LIST queue = { NULL, NULL };
  233.  
  234.     VERTEX_NODE *start_node = findVertex(&g->vertex_list, start);
  235.     q_push(&queue, start_node);
  236.     start_node->value->visited = true; // начиная с узла-источника
  237.     while (queue.head != NULL) {            // пока очередь не пуста
  238.         VERTEX_NODE *node = queue.head;                 // извлечь первый элемент в очереди
  239.         printf("Visit in %s\n", node->value->vertex_name);
  240.         queue.head = queue.head->next;
  241.         if (strcmp(node->value->vertex_name, goal->vertex_name) == 0) {
  242.             return true;                       // проверить, не является ли текущий узел целевым
  243.         }
  244.         for (VERTEX_NODE *child = node->value->neighbours->head;
  245.             child != NULL; child = child->next) // все преемники текущего узла, ...        
  246.             if (child->value->visited == false) {      // ... которые ещё не были посещены ...
  247.             q_push(&queue, child);                  // ... добавить в конец очереди...        
  248.             child->value->visited = true;           // ... и пометить как посещённые
  249.             }
  250.         free(node);
  251.     }
  252.     return false;                        // Целевой узел недостижим   
  253. }
  254. void q_push(VERTEX_LIST *q, VERTEX_NODE *nd)
  255. {
  256.     VERTEX_NODE *node = makeVertexNode(nd->value);
  257.     if (q->head == NULL)
  258.         q->head = q->tail = node;
  259.     else
  260.     {
  261.         q->tail->next = node;
  262.         node->prev = q->tail;
  263.         q->tail = node;
  264.     }
  265. }
  266.  
  267. void s_push(VERTEX_LIST *st, VERTEX_NODE *nd)
  268. {
  269.     VERTEX_NODE *temp = makeVertexNode(nd->value);
  270.     if (st->head != NULL)
  271.     {
  272.         temp->next = st->head;
  273.         temp->prev = NULL; //unused
  274.     }
  275.     st->head = temp;
  276. }
  277.  
  278. bool DFS_traversal(GRAPH *g, VERTEX *start, VERTEX *goal){
  279.     VERTEX_LIST st = { NULL, NULL };
  280.     for (VERTEX_NODE *temp = g->vertex_list.head; temp != NULL; temp = temp->next)
  281.         temp->value->visited = false;
  282.     VERTEX_NODE *start_node = findVertex(&g->vertex_list, start);
  283.     s_push(&st, start_node);
  284.     while (st.head != NULL)
  285.     {
  286.         VERTEX_NODE *node = st.head;
  287.         printf("Visit in %s\n", node->value->vertex_name);
  288.         if (strcmp(node->value->vertex_name, goal->vertex_name) == 0) {
  289.             return true;                       // проверить, не является ли текущий узел целевым
  290.         }
  291.         st.head = st.head->next;
  292.         if (!node->value->visited)
  293.         {
  294.             node->value->visited = true;
  295.             for (VERTEX_NODE *child = node->value->neighbours->head;
  296.                 child != NULL; child = child->next)
  297.                 // все содседи текущего узла, ...        
  298.             {
  299.                 s_push(&st, child);
  300.             }
  301.         }
  302.         free(node);
  303.     }
  304.     return false;
  305. }
  306.  
  307. void removeVertex(GRAPH *g, VERTEX *v)
  308. {
  309.     VERTEX_NODE *node = findVertex(&g->vertex_list, v);
  310.     for (VERTEX_NODE *child = node->value->neighbours->head; child != NULL; child = child->next) // все преемники текущего узла, ...           
  311.     {
  312.         removeNeibour(child, node->value);
  313.         removeEdgeV(g, node->value, child->value);
  314.         removeEdgeV(g, child->value, node->value);
  315.     }
  316.     if (node->next != NULL)
  317.         node->next->prev = node->prev;
  318.     node->prev->next = node->next;
  319.     free(node);
  320.    
  321. }
  322.  
  323. void removeNeibour(VERTEX_NODE *node, VERTEX *key)
  324. {
  325.     VERTEX_NODE *temp = node->value->neighbours->head;
  326.     if (strcmp(node->value->neighbours->head->value->vertex_name, key->vertex_name) == 0)
  327.     {
  328.         node->value->neighbours->head = temp->next;
  329.         if (node->value->neighbours->head!=NULL)
  330.             node->value->neighbours->head->prev = NULL;
  331.     }
  332.     else
  333.     {
  334.         for (temp = node->value->neighbours->head->next; temp != NULL; temp = temp->next)
  335.             if (strcmp(temp->value->vertex_name, key->vertex_name) == 0)
  336.             {
  337.                 if (temp->next != NULL)
  338.                     temp->next->prev = temp->prev;
  339.                 temp->prev->next = temp->next;
  340.                 free(temp);
  341.                 return;
  342.             }
  343.     }
  344.     free(temp);
  345.     return;
  346. }
  347. void removeEdge(GRAPH *g, EDGE *e)
  348. {
  349.     removeEdgeV(g, e->vertFrom, e->vertTo);
  350.     removeEdgeV(g, e->vertTo, e->vertFrom);
  351.     VERTEX_NODE *temp = findVertex(&g->vertex_list, e->vertFrom);  
  352.     removeNeibour(temp, e->vertTo);
  353.     temp = findVertex(&g->vertex_list, e->vertTo);
  354.     removeNeibour(temp, e->vertFrom);
  355.  
  356. }
  357.  
  358. void removeEdgeV(GRAPH *g, VERTEX *from, VERTEX *to)
  359. {
  360.     EDGE_NODE *temp = g->edge_list.head;
  361.     if ((strcmp(temp->value.vertFrom->vertex_name, from->vertex_name) == 0) &&
  362.         (strcmp(temp->value.vertTo->vertex_name, to->vertex_name) == 0))
  363.     {
  364.         g->edge_list.head = g->edge_list.head->next;
  365.         g->edge_list.head->prev = NULL;
  366.     }
  367.     for (temp = temp->next; temp != NULL; temp = temp->next)
  368.         if ((strcmp(temp->value.vertFrom->vertex_name, from->vertex_name) == 0) &&
  369.             (strcmp(temp->value.vertTo->vertex_name, to->vertex_name) == 0))
  370.         {
  371.             if (temp->next != NULL)
  372.                 temp->next->prev = temp->prev;
  373.             temp->prev->next = temp->next;
  374.         }
  375.     free(temp);
  376. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement