Atps classificação e pesquisa

36
UNIAN – CENTRO UNIVERSITÁRIO ANHANGUERA DE NITERÓI Ciência da Computação – 4º Período Classificação e Pesquisa Prof.ª Deise Galvão ATIVIDADES PRÁTICAS SUPERVISIONADAS - ETAPA 2 Tayline Queiroz – 7228576588 Fernanda Ledig -

description

Relatório 3 – Árvores Binárias de Pesquisa

Transcript of Atps classificação e pesquisa

UNIAN CENTRO UNIVERSITRIO ANHANGUERA DE NITERI

Cincia da Computao 4 PerodoClassificao e PesquisaProf. Deise Galvo

ATIVIDADES PRTICASSUPERVISIONADAS - ETAPA 2

Tayline Queiroz 7228576588 Fernanda Ledig -

Niteri2015Relatrio 3 rvores Binrias de Pesquisa

Passo 1 Fazer leitura de material disponibilizado.Passo 2

Fazer a discusso em equipe e tomar nota dos principais diferenciais entre os modelos de rvores apresentados nas leituras realizadas, focando na implementao das rvores no que tange:

Insero de dados em rvores Binrias.

Procure um local para inserir o novo n, comeando a procura a partir do n-raiz; Para cada n-raiz de uma sub-rvore, compare; se o novo n possui um valor menor do que o valor n raiz (vai para sub-rvore esquerda), ou se o valor maior que o valor no n-raiz (vai para sub-rvore direita); Se uma referncia (filho esquerdo/direito de um n raiz) nula atingida, coloque o novo n como sendo filho do n-raiz. Exemplo de implementao:def arvore_binaria_inserir(no, chave, valor): if no is None: return TreeNode(None, chave, valor, None) if chave == no.chave: return TreeNode(no.filho_esquerdo, chave, valor, no.filho_direito) if chave < no.chave: return TreeNode(arvore_binaria_inserir(no.filho_esquerdo, chave, valor), no.chave, no.valor, no.filho_direito) else: return TreeNode(no.filho_esquerdo, no.chave, no.valor, arvore_binaria_inserir(no.filho_direito, chave, valor)) } } }

Pesquisa de dados em rvores Binrias.

Comece a busca a partir do n-raiz; Para cada n-raiz de uma sub-rvore compare: Se o valor procurado menor que o valor no n-raiz (continua pela sub-rvore esquerda), ou se o valor maior que o valor no n-raiz (sub-rvore direita); caso o n contendo o valor pesquisado seja encontrado, retorne o n; caso contrrio retorne nulo.

Exemplos de Implementao:

# 'no' refere-se ao n-pai, neste casodef arvore_binaria_buscar(no, valor): if no is None: # valor no encontrado return None else: if valor == no.valor: # valor encontrado return no.valor elif valor < no.valor: # busca na subrvore esquerda return arvore_binaria_buscar(no.filho_esquerdo, valor) elif valor > no.valor: # busca na subrvore direita return arvore_binaria_buscar(no.filho_direito, valor)

Ordenao de dados em rvores Binrias.

Vrias operaes podem ser feitas usando rvores binrias de busca. Podemos citar, por exemplo, algoritmos de ordenao. O HeapSort um desses algoritmos que usam uma rvore para fazer a ordenao de uma lista de valores. No entanto, ao invs de usar uma rvore binria de busca, o algoritmo usa um tipo de rvore chamada Heap, onde a ordem dos elementos diferente. Usando uma rvore binria de busca, temos um cdigo de ordenao um pouco melhor, j que a ordenao feita na medida que os objetos entram na rvore. No entanto, devido essa necessidade de se adicionar o item ordenadamente cada insero, essa estrutura acaba no sendo a melhor escolha para ordenao. Aqui, temos um exemplo de como usaramos a rvore para ordenar. Veja o exemplo:

Exemplo de implementao:

//todosnaonulosdef organiza(valores): _arvore = None if valores is not None: _arvore = [] for _v in valores: insere(_arvore, _v) _res = [] percorre(_arvore, lambda valor: _res.append(valor)) return _res

Remoo de dados em rvores Binrias.

Para a remoo de um n em uma rvore binria, devem ser considerados trs casos:

Caso 1: o n folha O n pode ser retirado sem problema;

Caso 2: o n possui uma sub-rvore (esq./dir.) O n-raiz da sub-rvore (esq./dir.) ocupa o lugar do n retirado;

Caso 3: o n possui duas sub-rvores O n contendo o menor valor da sub-rvore direita pode ocupar o lugar; ou o maior valor da sub-rvore esquerda pode ocupar o lugar

Exemplo de implementao

def exclusao_em_arvore_binaria(n_arvore, valor): if n_arvore is None: return None # Valor no encontrado esquerda, n_valor, direita = n_arvore.esquerda, n_arvore.valor, n_arvore.direita if n_valor == valor: if esquerda is None: return direita elif direita is None: return esquerda else: valor_max, novo_esquerda = busca_max(esquerda) return TreeNode(novo_esquerda, valor_max, direita) elif valor < n_valor: return TreeNode(exclusao_em_arvore_binaria(esquerda, valor), n_valor, direita) else: return TreeNode(esquerda, n_valor, exclusao_em_arvore_binaria(direita, valor)) def busca_max(n_arvore): esquerda, n_valor, direita = n_arvore.esquerda, n_arvore.valor, n_arvore.direita if direita is None: return (n_valor, esquerda) else: (valor_max, novo_direita) = busca_max(direita) return (valor_max, (esquerda, n_valor, novo_direita))

Passo 3

Fazer as atividades apresentadas a seguir.

1. Desenvolver como base na estrutura de residncias, uma rvore Binria que represente a estrutura de residncias considerando: Ruas e Residncias. Medidores de Consumo de energia.

2. Implementar uma funo para cada uma das atividades discutidas no passo 2 pela equipe: Insero de dados em rvores Binrias. Pesquisa de dados em rvores Binrias. Ordenao de dados em rvores Binrias. Remoo de dados em rvores Binrias.

Cdigo Fonte: rvore Binria de Pesquisa

#include #include

// Estrutura do N, onde foi utilizado recursividade para os ponteiros da subarvore esquerda e direita. typedef struct No{ char rua[30]; char residencia[30]; int medidor; struct No *esquerda; struct No *direita;}No;

// Funo iniciar Arvore que inicializa a arvore binaria com o valor vazio.void iniciarArvore(No **Raiz){ *Raiz = NULL;}

/* Funo inserir, onde os valores que sero salvos no N da arvore,caso seja o primeiro elemento ser salvo como a raiz da arvore. Caso contrrio ser salvo de acordo com a sua devida posio.*/void inserir(No **pRaiz, char r[30], int med, char res[30]){ if(*pRaiz == NULL){ *pRaiz = (No *) malloc(sizeof(No)); (*pRaiz)->esquerda = NULL; (*pRaiz)->direita = NULL; strcpy((*pRaiz)->rua, r); strcpy((*pRaiz)->residencia, res); (*pRaiz)->medidor = med; }else{ if(med < (*pRaiz)->medidor) inserir(&(*pRaiz)->esquerda, r, med, res); if(med > (*pRaiz)->medidor) inserir(&(*pRaiz)->direita, r, med, res); }}

// Funo remover, onde ser eliminado um nico n por vez na arvore// e os elementos da sua subarvore esquerda e direita so realocadosNo *remover(No *r, int v){ if (r == NULL) return NULL; else if (r->medidor > v) r->esquerda = remover(r->esquerda, v); else if (r->medidor < v) r->direita = remover(r->direita, v); else { if (r->esquerda == NULL && r->direita == NULL) { free (r); r = NULL; } else if (r->esquerda == NULL) { No* t = r; r = r->direita; free (t); }}} // Exibio dos valores seguindo a seguinte ordem:// Subarvore Esquerda - Raiz - Subarvore Direitavoid EmOrdem(No *pRaiz){ if(pRaiz != NULL){ EmOrdem(pRaiz->esquerda); printf("---------------------------\n"); printf("Medidor.....:%d\n", pRaiz->medidor); printf("Rua.........:%s\n", pRaiz->rua); printf("Residencia..:%s\n", pRaiz->residencia); printf("---------------------------\n"); EmOrdem(pRaiz->direita); }}

// Exibio dos valores seguindo a seguinte ordem:// Raiz - Subarvore Esquerda - Subarvore Direitavoid PreOrdem(No *pRaiz){ if(pRaiz != NULL){ printf("---------------------------\n"); printf("Medidor.....:%d\n", pRaiz->medidor); printf("Rua.........:%s\n", pRaiz->rua); printf("Residencia..:%s\n", pRaiz->residencia); printf("---------------------------\n"); PreOrdem(pRaiz->esquerda); PreOrdem(pRaiz->direita); }}

// Exibio dos valores seguindo a seguinte ordem:// Subarvore Esquerda - Subarvore Direita - Raizvoid PosOrdem(No *pRaiz){ if(pRaiz != NULL){ PosOrdem(pRaiz->esquerda); PosOrdem(pRaiz->direita); printf("---------------------------\n"); printf("Medidor.....:%d\n", pRaiz->medidor); printf("Rua.........:%s\n", pRaiz->rua); printf("Residencia..:%s\n", pRaiz->residencia); printf("---------------------------\n"); }}

// Busca do medidor recebido como parmetro em toda a arvore No *arvorebusca(No *pRaiz,int med){ while (pRaiz != NULL && pRaiz->medidor != med) { if (pRaiz->medidor > med) pRaiz = pRaiz->esquerda; else pRaiz = pRaiz->direita; } return pRaiz;}

int main(int argc, char *argv[]){ char rua[30],res[30]; int op, med, es, busca; No *arvore; No *aux; iniciarArvore(&arvore); while (op!=5){ printf("---------------------------\n"); printf("| BEM VINDO AO CADASTRO |\n"); printf("| DE RESIDENCIAS |\n"); printf("---------------------------\n"); printf("---------------------------\n"); printf("MENU PRINCIPAL \n"); printf("1- Inserir um novo cadastro\n"); printf("2- Consultar os cadastros \n"); printf("3- Buscar nos cadastros \n"); printf("4- Remover um cadastro \n"); printf("5- Sair \n"); printf("---------------------------\n"); scanf("%d",&op); switch(op){ case 1: printf("Digite a rua da residencia: \n"); scanf("%s",&rua); printf("Digite o numero da residencia: \n"); scanf("%s",&res); printf("Digite o medidor de consumo: \n"); scanf("%d",&med); inserir(&arvore, rua, med, res); break; case 2: printf("Escolha a forma de exibio: \n"); printf("1 - Pre-Ordem \n"); printf("2 - Em Ordem \n"); printf("3 - Pos Ordem \n"); scanf("%d",&es); switch (es){ case 1: PreOrdem(arvore); break; case 2: EmOrdem(arvore); break; case 3: PosOrdem(arvore); break; } break; case 3: printf("Qual valor do medidor de consumo deseja pesquisar? \n"); scanf("%d",&busca); aux= arvorebusca(arvore, busca); if(aux->medidor == busca){ printf("O valor foi encontrado \n"); printf("---------------------------\n"); printf("Medidor.....:%d\n", aux->medidor); printf("Rua.........:%s\n", aux->rua); printf("Residencia..:%s\n", aux->residencia); printf("---------------------------\n"); } else printf("Valor nao encontrado \n"); break; case 4: printf("Qual valor do medidor de consumo deseja remover? \n"); scanf("%d",&busca); remover(arvore,busca); break; } } system("PAUSE"); return 0;}

Imagens e Resultados Obtidos:

Imagem 1: Inserir um novo cadastro, ou seja, insero de um novo n na rvore.

Imagem 2: Exibio da rvore em Pre-Ordem.

Imagem 3: Busca de um medidor de consumo.

ETAPA 4TEMA NOVO: MergeSort. Tabelas Hash estticas. Tabelas Hash dinmicas.

- Toda a etapa ser transformada em pesquisa terica.- De cada um dos temas propostos, dever ser pesquisado o funcionamento, principais caractersticas, principais aplicaes e exemplos de implementao em C.

MergesortOmergesort, ouordenaopor mistura, um exemplo dealgoritmo de ordenaodo tipodividir-para-conquistar.Sua ideia bsica consiste em Dividir (o problema em vrios subproblemas e resolver esses subproblemas atravs da recursividade) e conquistar (aps todos os subproblemas terem sido resolvidos ocorre a conquista que a unio das resolues dos subproblemas). Como o algoritmo do MergeSort usa a recursividade em alguns problemas esta tcnica no muito eficiente devido ao alto consumo de memria e tempo de execuo.Os trs passos teis dos algoritmos dividir-para-conquistar, oudivide and conquer, que se aplicam aomergesortso: Dividir: Dividir os dados em subsequncias pequenas; Conquistar: Classificar as duas metades recursivamente aplicando omerge sort; Combinar: Juntar as duas metades em um nico conjunto j classificado.

um algoritmo de ordenao estvel que se preserva a ordem de registros de chaves iguais. Isto , se tais registros aparecem na sequncia ordenada na mesma ordem em que esto na sequncia inicial. Esta propriedade til apenas quando h dados associados s chaves de ordenao. eficiente para ordenar listas, por exemplo se quisermos ordenar algo mais do que um vetor? rvores binrias j so todas pr-ordenadas, mas e as listas ligadas? Para isso, temos o MergeSort que funciona ainda melhor em listas ligadas em comparao que ele faz em matrizes. Isso evita a necessidade de um espao auxiliar, e se torna um simples e confivel algoritmo de ordenao. E ainda como bnus, muito estvel.

Resumo das Vantagens e desvantagem do mergesort: Vantagens: eficiente para ordenao externa Fcil implementao Recomendado para aplicaes com restrio de tempo Desvantagens: Utiliza memria auxiliar Alto consumo de memria

Implementao em C

Exemplo 1 :void merge (int M[5o], int inicio, int fim){int meio;comparaes[3]++;if (inicio < fim){meio = ((inicio + fim)/2);merge (M, inicio, meio);merge (M, meio+1, fim);intercala (M, inicio, meio, fim);}}void intercala (int M[50], int inicio, int fim){int primeiro, res, segundo, k;int C[]50;primeiro = res = inicio;segundo = meio + 1;while (primeiro