31
Estruturas de dados elementares Tipos básicos Estruturas Tabelas Listas Amontoados AED 2002/2003 – p.1/31

Estruturas de dados elementares - fenix.tecnico.ulisboa.pt · Estruturas de dados elementares Tipos bÆsicos Estruturas Tabelas Listas Amontoados AED 2002/2003 Œ p.1/31

  • Upload
    doduong

  • View
    225

  • 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

Apagamento em listas

x

t

x

t

t = x−>next;

x−>next = t−>next;

AED 2002/2003 – p.9/31

Inserção em listas

t

x

x

x

t

t−>next = x−>next;

x−>next = t;

AED 2002/2003 – p.10/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

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); }

}

AED 2002/2003 – p.31/31