/* Main sender function. Taken from the state diagram on slide 6, chapter 5 */ void sender(int window, int timeout) { int base = 1; int nextseqnum = 1; bool allsent = false; PQueue sendQ; pqueue_init(&sendQ, window); while ( !(allsent && pqueue_empty(&sendQ)) ) { int acknum = -1; /* Send new data */ if (!allsent && nextseqnum < base + window) { Packet* packet = add_packet(&sendQ, nextseqnum); if (packet == NULL) { allsent = true; } else { send_packet(packet); if (base == nextseqnum) start_timer(timeout); nextseqnum++; } } /* Attempt to receive an ACK. */ acknum = get_ack(0); if (acknum > 0) { base = acknum + 1; if (base == nextseqnum) stop_timer(); else start_timer(timeout); } /* Clean up the queue */ while (!pqueue_empty(&sendQ) && pqueue_head(&sendQ)->seqn < base) { pqueue_pop(&sendQ); } /* Handle timeouts */ if (cnt_active && cnt_time >= cnt_timeout) { start_timer(cnt_timeout); pqueue_map(&sendQ, &send_packet); } pqueue_debug_print(&sendQ); } pqueue_destroy(&sendQ); }
item_t pqueue_del_max(void) { assert(!pqueue_empty()); swap_item(&pq[1],&pq[N]); heapify_top_down(pq,1,N-1); return(pq[N--]); }
item_t pqueue_del_max(pqueue_t pq) { item_t max_item; assert(!pqueue_empty(pq)); copy_item(&max_item,&pq->root->item); pq->root=do_pqueue_del_max(pq->root); return(max_item); }
/* Applies a function to every packet in the queue */ void pqueue_map(PQueue* queue, void (*fn)(Packet*) ) { int i = queue->head; int last = (queue->head + queue->length - 1) % queue->maxsize; if (pqueue_empty(queue)) return; while( i != last ) { fn(&queue->packets[i]); i = PMOD(i+1, queue->maxsize); } if (pqueue_length(queue) > 1) fn(&queue->packets[last]); }
int main() { unsigned int maxSize = 10; pqueue_t pq = pqueue_empty(maxSize); bool exit = false; char *option = NULL; unsigned int *u = calloc(1,sizeof(unsigned int)); unsigned int v; do { option = print_menu(); switch(*option) { case ADD: printf("\nPor favor ingrese el nodo: "); if(!pqueue_is_full(pq)) { scanf("%u",&v); *u = v; pqueue_enqueue(pq, *u); printf("\nExito.\n"); } else { printf("La cola esta llena\n"); } break; case SHOW: if(!pqueue_is_empty(pq)) { *u = pqueue_fst(pq); printf("\nEl maximo es: %u\n",*u); } else { printf("La cola está vacia\n"); } break; case POP: if(!pqueue_is_empty(pq)) { pqueue_dequeue(pq); printf("\nSe elimino correctamente\n"); } break; case EXIT: exit = true; break; } free(option); option = NULL; } while(!exit); pq = pqueue_destroy(pq); }
graph_t kruskal(graph_t graph) { graph_t result = graph_empty(graph_vertices_count(graph)); unsigned int L, R, num_edges = graph_edges_count(graph); vertex_t l = NULL, r = NULL; pqueue_t Q = pqueue_empty(num_edges); union_find_t C = union_find_create(graph_vertices_count(graph)); edge_t E = NULL, *edges = graph_edges(graph); for (unsigned int i = 0; i < num_edges; i++) { pqueue_enqueue(Q, edges[i]); } free(edges); edges = NULL; while (!pqueue_is_empty(Q) && union_find_count(C) > 1) { E = edge_copy(pqueue_fst(Q)); l = edge_left_vertex(E); r = edge_right_vertex(E); L = union_find_find(C, vertex_label(l)); R = union_find_find(C, vertex_label(r)); if (L != R) { union_find_union(C, L, R); E = edge_set_primary(E, true); } else { E = edge_set_primary(E, false); } result = graph_add_edge(result, E); pqueue_dequeue(Q); } while (!pqueue_is_empty(Q)) { E = edge_copy(pqueue_fst(Q)); pqueue_dequeue(Q); E = edge_set_primary(E, false); result = graph_add_edge(result, E); } Q = pqueue_destroy(Q); C = union_find_destroy(C); return result; }
graph_t kruskal(graph_t graph) { /* Computes a MST of the given graph. * * This function returns a copy of the input graph in which * only the edges of the MST are marked as primary. The * remaining edges are marked as secondary. * * The input graph does not change. * */ graph_t mst; union_find_t uf; pqueue_t pq; edge_t *edges; edge_t e; unsigned int left, right, n, m; /* Inicialización */ n = graph_vertices_count(graph); m = graph_edges_count(graph); mst = graph_empty(n); uf = union_find_create(n); pq = pqueue_empty(m); /* Llenar `pq` */ edges = graph_edges(graph); for (unsigned int j = 0; j < m; j++) { pqueue_enqueue(pq, edges[j]); } /* Ahora las aristas están en `pq` */ free(edges); edges = NULL; /* Principal */ while (!pqueue_is_empty(pq) && union_find_count(uf) > 1) { e = edge_copy(pqueue_fst(pq)); left = vertex_label(edge_left_vertex(e)); right = vertex_label(edge_right_vertex(e)); left = union_find_find(uf, left); right = union_find_find(uf, right); if (!union_find_connected(uf, left, right)) { e = edge_set_primary(e, true); union_find_union(uf, left, right); } else { e = edge_set_primary(e, false); } mst = graph_add_edge(mst, e); pqueue_dequeue(pq); } /* Agregar aristas restantes como secundarias */ while (!pqueue_is_empty(pq)) { e = edge_copy(pqueue_fst(pq)); e = edge_set_primary(e, false); mst = graph_add_edge(mst, e); pqueue_dequeue(pq); } /* Destroy */ uf = union_find_destroy(uf); pq = pqueue_destroy(pq); return (mst); }