Реализация фибоначчиевой кучи для оптимизации алгоритма Дейкстры - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Это реализация фибоначивей кучи для оптимизации алгоритма Дейкстры, единственную реализацию нашел на плюсах, помогите перевести на Си, заранее спасибо!
Листинг программы
  1. сonst int INF = 1000000000;
  2. int main() {
  3. int n;
  4. ... чтение n ...
  5. vector < vector < pair<int,int> > > g (n);
  6. ... чтение графа ...
  7. int s = ...; // стартовая вершина
  8. vector<int> d (n, INF), p (n);
  9. d[s] = 0;
  10. priority_queue < pair<int,int> > q;
  11. q.push (make_pair (0, s));
  12. while (!q.empty()) {
  13. int v = q.top().second, cur_d = -q.top().first;
  14. q.pop();
  15. if (cur_d > d[v]) continue;
  16. for (size_t j=0; j<g[v].size(); ++j) {
  17. int to = g[v][j].first,
  18. len = g[v][j].second;
  19. if (d[v] + len < d[to]) {
  20. d[to] = d[v] + len;
  21. p[to] = v;
  22. q.push (make_pair (-d[to], to));
  23. }
  24. }
  25. }
  26. }

Решение задачи: «Реализация фибоначчиевой кучи для оптимизации алгоритма Дейкстры»

textual
Листинг программы
  1. #include <stdio.h>
  2. #include <malloc.h>
  3. #include <limits.h>
  4. #define MAX_PQSIZE  16
  5. typedef unsigned int uint_t;
  6.  
  7. typedef struct {
  8.     uint_t v, d;
  9. } vert_t;
  10.  
  11. typedef struct {
  12.     uint_t p, d, v;
  13. } res_t;
  14.  
  15. typedef struct {
  16.     vert_t* arr;
  17.     uint_t  cnt;
  18.     uint_t  len;
  19.     int (*cmp)(const vert_t*, const vert_t*);
  20. } pqueue_t;
  21.  
  22. static void _pqueue_heapify(pqueue_t* pq, size_t i);
  23. static int _pqueue_alloc(pqueue_t* pq, size_t n);
  24. inline void   pqueue_init(pqueue_t* pq, int (*cmp)(const vert_t*, const vert_t*));
  25. inline vert_t pqueue_top(pqueue_t* pq);
  26. inline int    pqueue_empty(const pqueue_t* pq);
  27. inline size_t pqueue_size(const pqueue_t* pq);
  28. int    pqueue_push(pqueue_t* pq, uint_t v, uint_t d);
  29. void   pqueue_pop(pqueue_t* pq);
  30. void   pqueue_clear(pqueue_t* pq);
  31.  
  32. //-----------------
  33.  
  34. typedef struct node {
  35.     uint_t index;
  36.     uint_t cost;
  37.     struct node* next;
  38. } node_t;
  39.  
  40. typedef struct graph {
  41.     node_t** arr;
  42.     size_t   cnt;
  43. } graph_t;
  44.  
  45. static int node_new(graph_t* q, uint_t x, uint_t y, uint_t cost);
  46. inline void graph_init(graph_t* g);
  47. int    graph_input(FILE* _in, graph_t* g);
  48. void   graph_free(graph_t* g);
  49. res_t* graph_shortest(graph_t* g, uint_t s);
  50.  
  51.  
  52. int main(void){
  53.     res_t*  res;
  54.     uint_t  i, j, s, t;
  55.     graph_t g;
  56. /*  ввод из файла
  57.     FILE* fp = fopen("graph.txt", "rt");
  58.     if(fp == NULL)
  59.         return 1;
  60.  
  61.     graph_init(&g);
  62.     if(! graph_input(fp, &g)){
  63.         fclose(fp);
  64.         return 2;
  65.     }
  66.     fclose(fp);
  67. */
  68.     graph_init(&g);
  69.     if(! graph_input(stdin, &g))
  70.         return 2;
  71.  
  72.     //найти путь от нулевой вершины во все другие
  73.     s   = 0;
  74.     res = graph_shortest(&g, s);
  75.     if(res == NULL){
  76.         graph_free(&g);
  77.         free(res);
  78.         return 3;
  79.     }
  80.  
  81.     //вывод всех путей от заданной вершины во все другие
  82.     for(i = 0; i < g.cnt; ++i){
  83.         if(i == s)
  84.             continue;
  85.  
  86.         j = 0;
  87.         res[j++].v = i;
  88.         for(t = i; t != s; t = res[t].p)
  89.             res[j++].v = res[t].p;
  90.  
  91.         printf("length: %u  path: ", res[i].d);
  92.         for(t = 0; t < j; ++t)
  93.             printf("%u ", res[j - 1 - t].v);
  94.         putchar('\n');
  95.     }
  96.     free(res);
  97.     graph_free(&g);
  98.     return 0;
  99. }
  100.  
  101. static int compare(const vert_t* a, const vert_t* b){
  102.     return (a->d < b->d);
  103. }
  104.  
  105. //поиск кратчайшего пути "алгоритмом Дейкстра"
  106. res_t* graph_shortest(graph_t* g, uint_t s){
  107.     const node_t* k;
  108.     res_t*   res;
  109.     vert_t   ver;
  110.     uint_t   i;
  111.     pqueue_t pq;
  112.  
  113.     res = (res_t*)malloc(g->cnt * sizeof(res_t));
  114.     if(res == NULL)
  115.         return NULL;
  116.  
  117.     for(i = 0; i < g->cnt; ++i){
  118.         res[i].d = UINT_MAX;
  119.         res[i].v = res[i].p = 0;
  120.     }
  121.  
  122.     res[s].d = 0;
  123.     pqueue_init(&pq, compare);
  124.     if(! pqueue_push(&pq, s, 0))
  125.         goto err;
  126.  
  127.     while(! pqueue_empty(&pq)){
  128.         ver = pqueue_top(&pq);
  129.         pqueue_pop(&pq);
  130.         if(ver.d > res[ver.v].d)
  131.             continue;
  132.  
  133.         for(k = g->arr[ver.v]; k != NULL; k = k->next){
  134.  
  135.             if((res[ver.v].d + k->cost) < res[k->index].d){
  136.                 res[k->index].d = res[ver.v].d + k->cost;
  137.                 res[k->index].p = ver.v;
  138.                 if(! pqueue_push(&pq, k->index, res[k->index].d))
  139.                     goto err;
  140.             }
  141.         }
  142.     }
  143.     pqueue_clear(&pq);
  144.     return res;
  145. err:
  146.     free(res);
  147.     pqueue_clear(&pq);
  148.     return NULL;
  149. }
  150.  
  151. /* ввод из входного потока неориентированного взвешенного графа
  152.    формат представлен в виде списка рёбер графа:
  153.    кол-во вершин  кол-во рёбер
  154.    ребро(2-вершины)  вес */
  155. int graph_input(FILE* _in, graph_t* g){
  156.     uint_t i, vn, em, x, y, cost;
  157.     if((fscanf(_in, "%u %u", &vn, &em) != 2) || (vn <= 1) || (em <= 1))
  158.         return 0;
  159.  
  160.     g->arr = (node_t**)malloc(vn * sizeof(node_t*));
  161.     if(g->arr == NULL)
  162.         return 0;
  163.  
  164.     g->cnt = vn;
  165.     for(i = 0; i < vn; ++i)
  166.         g->arr[i] = NULL;
  167.  
  168.     for(i = 0; i < em; ++i){
  169.         if(fscanf(_in, "%u %u %u", &x, &y, &cost) == 3){
  170.             if((x < vn) && (y < vn)){
  171.                 if(! node_new(g, x, y, cost))
  172.                     goto err;
  173.                 if(! node_new(g, y, x, cost))
  174.                     goto err;
  175.             }
  176.         } else
  177.             break;
  178.     }
  179.     return 1;
  180. err:
  181.     graph_free(g);
  182.     return 0;
  183. }
  184.  
  185. //удаление графа из памяти
  186. void graph_free(graph_t* g){
  187.     node_t* t;
  188.     uint_t  i;
  189.     for(i = 0; i < g->cnt; ++i){
  190.         while(g->arr[i] != NULL){
  191.             t = g->arr[i];
  192.             g->arr[i] = g->arr[i]->next;
  193.             free(t);
  194.         }
  195.     }
  196.     if(g->arr != NULL)
  197.         free(g->arr);
  198.     g->arr = NULL;
  199.     g->cnt = 0;
  200. }
  201.  
  202. inline void graph_init(graph_t* g){
  203.     g->arr = NULL;
  204.     g->cnt = 0;
  205. }
  206.  
  207. static int node_new(graph_t* q, uint_t x, uint_t y, uint_t cost){
  208.     node_t* p = (node_t*)malloc(sizeof(node_t));
  209.     if(p != NULL){
  210.         p->next   = q->arr[x];
  211.         p->index  = y;
  212.         p->cost   = cost;
  213.         q->arr[x] = p;
  214.     }
  215.     return (p != NULL);
  216. }
  217.  
  218. //---------------------
  219.  
  220. //вставка в приоритетную очередь
  221. int pqueue_push(pqueue_t* pq, uint_t v, uint_t d){
  222.     vert_t t;
  223.     size_t i, p;
  224.     if(! _pqueue_alloc(pq, 1))
  225.         return 0;
  226.    
  227.     pq->arr[pq->cnt].v = v;
  228.     pq->arr[pq->cnt].d = d;
  229.     if(++pq->cnt == 1)
  230.         return 1;
  231.  
  232.     i = pq->cnt - 1;
  233.     p = (i - 1) >> 1;
  234.     while((i > 0) && !(*pq->cmp)(&pq->arr[p], &pq->arr[i])){
  235.         t = pq->arr[p];
  236.         pq->arr[p] = pq->arr[i];
  237.         pq->arr[i] = t;
  238.  
  239.         i = p;
  240.         p = (i - 1) >> 1;
  241.     }
  242.     return 1;
  243. }
  244.  
  245. //удаление элемента
  246. void pqueue_pop(pqueue_t* pq){
  247.     if(pq->cnt > 0){
  248.         pq->arr[0] = pq->arr[--pq->cnt];
  249.         _pqueue_heapify(pq, 0);
  250.     }
  251. }
  252.  
  253. //удаление всех
  254. void pqueue_clear(pqueue_t* pq){
  255.     if(pq->arr != NULL)
  256.         free(pq->arr);
  257.     pq->arr = NULL;
  258.     pq->cnt = 0;
  259.     pq->len = MAX_PQSIZE;
  260. }
  261.  
  262. //инициализация
  263. inline void pqueue_init(pqueue_t* pq, int (*cmp)(const vert_t*, const vert_t*)){
  264.     pq->arr = NULL;
  265.     pq->cnt = 0;
  266.     pq->len = MAX_PQSIZE;
  267.     pq->cmp = cmp;
  268. }
  269.  
  270. inline vert_t pqueue_top(pqueue_t* pq){ return pq->arr[0]; }
  271. inline int    pqueue_empty(const pqueue_t* pq){ return (pq->cnt == 0); }
  272. inline size_t pqueue_size(const pqueue_t* pq) { return pq->cnt; }
  273.  
  274. static void _pqueue_heapify(pqueue_t* pq, size_t i){
  275.     vert_t t;
  276.     size_t r, l, h;
  277.     while(1){
  278.         l = (i << 1) + 1;
  279.         r = l + 1; //(i << 1) + 2
  280.        
  281.         if((l < pq->cnt) && (*pq->cmp)(&pq->arr[l], &pq->arr[i]))
  282.             h = l;
  283.         else
  284.             h = i;
  285.  
  286.         if((r < pq->cnt) && (*pq->cmp)(&pq->arr[r], &pq->arr[h]))
  287.             h = r;
  288.  
  289.         if(h != i){
  290.             t = pq->arr[i];
  291.             pq->arr[i] = pq->arr[h];
  292.             pq->arr[h] = t;
  293.             i = h;
  294.         } else
  295.             break;
  296.     }
  297. }
  298.  
  299. static int _pqueue_alloc(pqueue_t* pq, size_t n){
  300.     size_t  m;
  301.     vert_t* t;
  302.     if(pq->arr == NULL){
  303.         m       = (n > pq->len) ? n : pq->len;
  304.         pq->arr = (vert_t*)malloc(m * sizeof(vert_t));
  305.         if(pq->arr == NULL)
  306.             return 0;
  307.         pq->len = m;
  308.     } else if((pq->cnt + n) >= pq->len){
  309.         m = pq->cnt + n + (pq->len >> 1);
  310.         t = (vert_t*)realloc(pq->arr, m * sizeof(vert_t));
  311.         if(t == NULL)
  312.             return 0;
  313.         pq->arr = t;
  314.         pq->len = m;
  315.     }
  316.     return 1;
  317. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы