AED 2002/2003 p.1/31 Estruturas de dados elementares Tipos básicos Estruturas Tabelas Listas Amontoados
AED 2002/2003 p.2/31 Tipos básicos Inteiros Reais Caracteres Ponteiros short a1; int a2; long a3; float x1; double x2; char c1; int *p1;
Tipos compostos Estruturas struct point float x; float y; ; Uniões struct line_point int type; union struct point float x,y; struct line float x1,y1; float x2,y2; ; AED 2002/2003 p.3/31
AED 2002/2003 p.4/31 Tabelas Colecção de items Inteiros, reais, caracteres Estruturas ou uniões Tabelas, Ponteiros Guardados em posições consecutivas de memória int tab[n]; 0 1 2 3 n 1 Programador é responsável por respeitar limites
AED 2002/2003 p.5/31 Tabelas Em C, tabelas podem ser: De dimensão fixa Alocadas dinamicamente #define N 100 int tab1[n]; int *tab2 = malloc(n*sizeof(int)); Acesso a tabelas alternativo Com ponteiros Usando aritmética de ponteiros x = tab2[i]; y = *(tab2+i);
AED 2002/2003 p.6/31 Exemplo: crivo de Eratóstenes #define N 1000 main() int i,j,a[n]; for (i=2;i<n;i++) a[i] = 1; for (i=2;i<n;i++) if (a[i]) for(j=i; i*j<n; j++) a[i*j] = 0; for (i=2; i<n; i++) if (a[i]) printf("%4d",i); printf("\n");
AED 2002/2003 p.7/31 Exemplo: simulação de moedas ao ar #include <stdlib.h> int heads() return rand() < RAND_MAX/2; main(int argc, char *argv[]) int i, j, cnt; int N = atoi(argv[1]), M = atoi(argv[2]); int *f = malloc((n+1)*sizeof(int)); for (j = 0; j <= N; j++) f[j] = 0; for (i = 0; i < M; i++, f[cnt]++) for (cnt = 0, j = 0; j <= N; j++) if (heads()) cnt++; for (j = 0; j <= N; j++) printf("%2d ", j); for (i = 0; i < f[j]; i+=10) printf("*"); printf("\n");
AED 2002/2003 p.8/31 Listas simplesmente ligadas Conjunto de nós Cada nó contém Informação útil Ponteiro para outro nó typedef struct node *link; struct node Item item; link next;;
AED 2002/2003 p.9/31 Apagamento em listas x t = x >next; t x x >next = t >next; t
AED 2002/2003 p.10/31 Inserção em listas x t x t >next = x >next; t x x >next = t;
AED 2002/2003 p.11/31 Inversão de lista link reverse(link x) link t, y = x, r = NULL; while (y!= NULL) t = y->next; y->next = r; r = y; y = t; return r;
AED 2002/2003 p.12/31 Insertion sort Versão 1 static int *vect; void init() int i; vect = (int*) malloc(n*sizeof(int)); for (i=0; i<n; i++) vect[i] = rand() % M; void print() int i; printf("[ "); for (i=0; i<n; i++) printf("%d ", vect[i]); printf("]\n");
AED 2002/2003 p.13/31 Insertion sort Versão 1 void isort() /* Utiliza tabela */ int i, j; for (i=1; i<n; i++) int key = vect[i]; j = i-1; while (j>=0 && vect[j] > key) vect[j+1] = vect[j]; j--; vect[j+1] = key;
AED 2002/2003 p.14/31 Insertion sort Versão 2 typedef int Item; typedef struct node *link; struct node Item item; link next; ; static struct node *head; void init() int i; link pt, pv; head = NULL; for (i = 0; i < N; i++) pt = malloc(sizeof *pt); pt->next = NULL; pt->item = rand() % M; if (!head) head = pt; else pv->next = pt; pv = pt;
AED 2002/2003 p.15/31 Insertion sort Versão 2 void isort() /* Utiliza lista */ link pa, pb, px, py, pz; for (px = head->next, py = head; px!= NULL; px = pz) py->next = px->next; pz = px->next; for (pb=head, pa=pb; pb!=pz; pa=pb, pb=pb->next) if (pb->item > px->item) break; if (pa == pb) head = px; else pa->next = px; px->next = pb; if (pb == pz) py = px;
AED 2002/2003 p.16/31 Insertion sort Versão 3 typedef int Item; typedef struct node *link; struct node Item item; link next; ; static struct node *heada, *headb; void init() int i; link t, u, a; heada = (link) malloc(sizeof(*heada)); headb = (link) malloc(sizeof(*headb)); a = heada; for (i = 0, t = a; i < N; i++) t->next = malloc(sizeof *t); t = t->next; t->next = NULL; t->item = rand() % M;
AED 2002/2003 p.17/31 Insertion sort Versão 3 void isort() /* Utiliza lista com sentinela */ link t, u, x, b; b = headb; b->next = NULL; for (t = heada->next; t!= NULL; t = u) u = t->next; for (x = b; x->next!= NULL; x = x->next) if (x->next->item > t->item) break; t->next = x->next; x->next = t; heada->next = headb->next; headb->next = NULL;
AED 2002/2003 p.18/31 Lista Duplamente Ligada struct iitem int value; struct iitem *next; struct iitem *prev; ; typedef struct iitem IntItem; typedef IntItem* IntItemPtr; static IntItemPtr first = NULL; static IntItemPtr last = NULL; static IntItemPtr alloc_item() return (IntItemPtr) malloc(sizeof(intitem));
AED 2002/2003 p.19/31 Lista Duplamente Ligada void init() first = alloc_item(); last = alloc_item(); first->next = last; first->prev = NULL; last->next = NULL; last->prev = first;
AED 2002/2003 p.20/31 Lista Duplamente Ligada int insert(int value) IntItemPtr px, nitem; for (px = first->next; px!= last && px->value < value; px = px->next) ; if (px!= last && px->value == value) return 0; /* no duplicates */ nitem = alloc_item(); nitem->value = value; px->prev->next = nitem; nitem->prev = px->prev; nitem->next = px; px->prev = nitem; return 1;
AED 2002/2003 p.21/31 Lista Duplamente Ligada int delete(int value) IntItemPtr px; for (px = first->next; px!= last && px->value < value; px = px->next) ; if (px && px->value == value) px->prev->next = px->next; px->next->prev = px->prev; free(px); return 1; return 0;
AED 2002/2003 p.22/31 Lista Duplamente Ligada void delete_list() IntItemPtr px; while (px = first) first = first->next; free(px); first = last = NULL; void print_list() IntItemPtr px; printf("[ "); for (px = first->next; px!= last; px = px->next) printf("%d ", px->value); printf("]\n");
AED 2002/2003 p.23/31 Interface para processamento de listas #include <stdlib.h> #include "list.h" link freelist; void initnodes(int N) int i; freelist = malloc((n+1)*(sizeof *freelist)); for (i = 0; i < N+1; i++) freelist[i].next = &freelist[i+1]; freelist[n].next = NULL; link newnode(int i) link x = deletenext(freelist); x->item = i; x->next = x; return x;
AED 2002/2003 p.24/31 Interface para processamento de listas void freenode(link x) insertnext(freelist, x); void insertnext(link x, link t) t->next = x->next; x->next = t; link deletenext(link x) link t = x->next; x->next = t->next; return t; link Next(link x) return x->next; int Item(link x) return x->item;
Amontoados Uma árvore está heap-ordered se a chave de cada nó for maior ou igual às chaves dos seus filhos X T O G S M N A E R A I Nenhum nó tem uma chave superior à raiz Uma árvore binária é completa se apenas o último nível estiver incompleto, e faltarem apenas os nós mais à direita. AED 2002/2003 p.25/31
AED 2002/2003 p.26/31 Amontoados X T O G S M N A E R A I 1 2 3 4 5 6 7 8 9 10 11 12 X T O G S M N A E R A I Parente do nó é o nó Filhos do nó são os nós e
AED 2002/2003 p.27/31 Operações em amontoados: fixup Chamada quando a prioridade de um nó é aumentada Nó tem de ser deslocado para cima fixup(item a[], int k) while (k > 1 && less(a[k/2], a[k])) exch(a[k], a[k/2]); k = k/2;
AED 2002/2003 p.28/31 Operações em amontoados: fixdown Chamada quando a prioridade de um nó é diminuída Nó tem de ser deslocado para baixo, até ao último nível ou até que a prioridade do nó alterado seja maior que ambos os filhos fixdown(item a[], int k, int N) int j; while (2*k <= N) j = 2*k; if (j < N && less(a[j], a[j+1])) j++; if (!less(a[k], a[j])) break; exch(a[k], a[j]); k = j;
AED 2002/2003 p.29/31 Fila de prioridades #include <stdlib.h> #include "Item.h" static Item *pq; static int N; void PQinit(int maxn) pq = malloc((maxn+1)*sizeof(item)); N = 0; int PQempty() return N == 0; void PQinsert(Item v) pq[++n] = v; fixup(pq, N); Item PQdelmax() exch(pq[1], pq[n]); fixdown(pq, 1, N-1); return pq[n--];
AED 2002/2003 p.30/31 Ordenação com fila de prioridades void PQsort(Item a[], int l, int r) int k; PQinit(r-l+1); for (k = l; k <= r; k++) PQinsert(a[k]); for (k = r; k >= l; k--) a[k] = PQdelmax();
AED 2002/2003 p.31/31 Heapsort #define pq(a) a[l-1+a] void heapsort(item a[], int l, int r) int k, N = r-l+1; for (k = N/2; k >= 1; k--) fixdown(&pq(0), k, N); while (N > 1) exch(pq(1), pq(n)); fixdown(&pq(0), 1, --N);