Upload
doduong
View
227
Download
0
Embed Size (px)
Citation preview
Estruturas de dados elementares
Tipos básicos
Estruturas
Tabelas
Listas
Amontoados
AED 2002/2003 – p.1/31
Tipos básicos
Inteiros
Reais
Caracteres
Ponteiros
short a1;
int a2;
long a3;
float x1;
double x2;
char c1;
int *p1;
AED 2002/2003 – p.2/31
Tipos compostos
Estruturasstruct point {
float x;
float y;
};
Uniõesstruct line_point {
int type;
union {
struct point {
float x,y;
}
struct line {
float x1,y1;
float x2,y2;
}
}
}; AED 2002/2003 – p.3/31
Tabelas
Colecção de itemsInteiros, reais, caracteresEstruturas ou uniõesTabelas, 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.4/31
Tabelas
Em C, tabelas podem ser:De dimensão fixaAlocadas 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.5/31
Exemplo: crivo de Eratóstenes
#define N 1000main() {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.6/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.7/31
Listas simplesmente ligadas
Conjunto de nós
Cada nó contémInformação útilPonteiro para outro nó
typedef struct node *link;struct node {Item item; link next;};
AED 2002/2003 – p.8/31
Inversão de listalink 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.11/31
Insertion sort – Versão 1static 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.12/31
Insertion sort – Versão 1void 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.13/31
Insertion sort – Versão 2typedef 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.14/31
Insertion sort – Versão 2void 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.15/31
Insertion sort – Versão 3typedef 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.16/31
Insertion sort – Versão 3void 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.17/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.18/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.19/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.20/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.21/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.22/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.23/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; }
AED 2002/2003 – p.24/31
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ívelestiver incompleto, e faltarem apenas os nós mais àdireita. AED 2002/2003 – p.25/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 12X 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.26/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.27/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ívelou até que a prioridade do nó alterado seja maior queambos 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.28/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.29/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.30/31