/* Last edited on 2009-12-14 17:44:21 by stolfilocal */ #include #include #define True 1 #define False 0 filaCandidatos_t criaFila(void) { filaCandidatos_t fila; fila.n = 0; fila.prim[QFILA_Lo] = NULL; fila.prim[QFILA_Hi] = NULL; fila.prim[QFILA_Ex] = NULL; return fila; } candidato_t *insereCandidato ( filaCandidatos_t *fila, char *nome ,int escala, float distLo, float distHi, float distMd, float distAcc, Interval distEstIA, cmpCands_t *cmp ) { candidato_t *novo = novoCandidato(nome,escala,distLo,distHi,distMd,distAcc,distEstIA); insereCandidatoNaLista(&(fila->prim[QFILA_Lo]), novo, QFILA_Lo, comparaLo); insereCandidatoNaLista(&(fila->prim[QFILA_Hi]), novo, QFILA_Hi, comparaHi); insereCandidatoNaLista(&(fila->prim[QFILA_Ex]), novo, QFILA_Ex, cmp); fila->n++; return novo; } void reordenaFila(filaCandidatos_t *fila,cmpCands_t *cmp) { // Inverte lista de candidatos, coloca em {inv}: candidato_t *old = fila->prim[QFILA_Ex]; candidato_t *inv = NULL; while (old != NULL) { candidato_t *tmp = old; old = old->prox[QFILA_Ex]; tmp->prox[QFILA_Ex] = inv; inv = tmp; } // Re-insere candidatos na lista: fila->prim[QFILA_Ex] = NULL; while (inv != NULL) { candidato_t *tmp = inv; inv = inv->prox[QFILA_Ex]; insereCandidatoNaLista(&(fila->prim[QFILA_Ex]), tmp, QFILA_Ex, cmp); } } candidato_t *buscaCandidato(filaCandidatos_t *fila,char *nome) { candidato_t *aux = fila->prim[0]; while ((aux!=NULL) && (strcmp(aux->nome, nome) != 0)) { aux = aux->prox[0]; } return aux; } void retiraCandidato(filaCandidatos_t *fila,candidato_t *cand) { int achouLo = excluiCandidatoDaLista(&(fila->prim[QFILA_Lo]), cand, QFILA_Lo); int achouHi = excluiCandidatoDaLista(&(fila->prim[QFILA_Hi]), cand, QFILA_Hi); int achouEx = excluiCandidatoDaLista(&(fila->prim[QFILA_Ex]), cand, QFILA_Ex); assert((achouLo == achouHi) && (achouHi == achouEx)); if (achouLo) { fila->n--; free(cand); } } void freeFila(filaCandidatos_t *fila) { candidato_t *aux = fila->prim[QFILA_Lo], *ele = NULL; while (aux != NULL) { ele = aux; aux = aux->prox[QFILA_Lo]; free(ele); } } void exibeFila(filaCandidatos_t *fila,QFILA_t qual) { candidato_t *aux = fila->prim[qual]; while (aux != NULL) { exibeCand(aux); aux = aux->prox[qual]; } } void exibeCand(candidato_t *cand) { fprintf(stderr, "%s %02d [ %8.6f %8.6f ] ~ %8.6f, %8.6f\n", cand->nome, cand->k, cand->distLo, cand->distHi, cand->distMd, cand->distAcc); } // Internas candidato_t *novoCandidato ( char *nome, int k, float distLo, float distHi, float distMd, float distAcc, Interval distEstIA ) { candidato_t *novo=NULL; novo=malloc(sizeof(candidato_t)); (*novo) = (candidato_t) { .nome = nome, .k = k, .distLo = distLo, .distHi = distHi, .distMd = distMd, .distAcc = distAcc, .distEstIA = distEstIA, .prox = {NULL,NULL,NULL}, .ante = {NULL,NULL,NULL} }; // int qual; // for (qual=0; qual < 3; qual++) { novo->prox[qual] = novo->ante[qual] = NULL; } return novo; } void insereCandidatoNaLista(candidato_t **prim,candidato_t *cand,QFILA_t qual, cmpCands_t *cmp) { candidato_t *pro = (*prim); candidato_t *ant = NULL; while ((pro != NULL) && (cmp(cand,pro) > 0)) { ant = pro; pro = pro->prox[qual]; } cand->prox[qual] = pro; cand->ante[qual] = ant; if (ant != NULL) { ant->prox[qual] = cand; } else { (*prim) = cand; } if (pro != NULL) { pro->ante[qual] = cand; } else { /* nada a fazer pois nao estamos guardando o ultimo. */ } } candidato_t *indexaCand(filaCandidatos_t *fila,int i,QFILA_t qual) { int cont = 0; candidato_t *aux = fila->prim[qual]; // Primeiro na ordem especificada candidato_t *ant = NULL; while ((aux != NULL) && (cont < i)) { assert(aux->distLo <= aux->distLo); ant = aux; aux = aux->prox[qual]; cont++; } return aux; } int excluiCandidatoDaLista(candidato_t **prim,candidato_t *cand,QFILA_t qual) { candidato_t *aux = (*prim); while ((aux != NULL) && (aux != cand)) { aux = aux->prox[qual]; } if (aux == NULL) { return 0; } if (aux->ante[qual] != NULL) { aux->ante[qual]->prox[qual] = aux->prox[qual]; } else { (*prim) = aux->prox[qual]; } if (aux->prox[qual] != NULL) { aux->prox[qual]->ante[qual] = aux->ante[qual]; } else { /* nada a fazer pois nao estamos guardando o ultimo. */ } return 1; } int comparaLo(candidato_t *x,candidato_t *y) { if (x->distLo < y->distLo) { return -1; } else if (x->distLo > y->distLo) { return +1; } else if (x->k > y->k) { return -1; } else if (x->k < y->k) { return +1; } else {return 0; } } int comparaHi(candidato_t *x,candidato_t *y) { if (x->distHi < y->distHi) { return -1; } else if (x->distHi > y->distHi) { return +1; } else if (x->k > y->k) { return -1; } else if (x->k < y->k) { return +1; } else {return 0; } }