Tabela Hash feita em C
Publicado por Marcos Augusto (última atualização em 05/12/2017)
[ Hits: 47.384 ]
Homepage: ...
Download TabelasHash.rar (versão 2)
Neste trabalho foram criadas três páginas:
hash. h :: nela está contida a estrutura do hash e os protótipos de todas funções que foram usadas no programa.
hash.c :: nela está contida a elaboração de todas as funções implementadas neste programa.
hash.cpp :: nela está a função principal para a compilação de todo o programa.
Os códigos foram elaborados, somente para serem compilados no Dev-C++: http://sourceforge.net/projects/orwelldevcpp/
Todos os códigos devem estar salvos na mesma pasta para seu correto funcionamento.
Versão 2 - Enviado por Marcos Augusto em 21/11/2017
Changelog: Correção do ultimo envio, que no caso enviei um código incorreto co a descrição
Arquivo hash.h: #define tam 677 /*hash.h armazena a estrutura e os prototipos das funcaoes*/ struct dados { int info; struct dados *prox; }; typedef struct dados Dados; typedef Dados* Hash[tam]; int funcaoHash(int num);/**/ void inicializaHash(Hash tab); /**/ void insereHash(Hash tab,int num); void buscaHash(Hash tab, int num); void imprimeHash(Hash tab); void removeHash(Hash tab, int num); void criarArquivo(FILE* arquivo); void reescreveArquivo(FILE* arquivo); void escreveArquivo(FILE* arquivo, int elemento); int carreagaArquivo(Hash tab); void linhaAnimada(int q, int a); void linha(int q, int a); void cor(WORD cor); void posicao(int x, int y); void menuHash(int *num); void menuEstatistica(int *num); float porcentagemHash(Hash tab); void indiceColisao(Hash tab); int quantidadeColisao(Hash tab); void posicoesVazias(Hash tab); void imprimeColisao(Hash tab, int pos); void numeroAleatorio(); void lerNumero(int *num); void lerNumero1(int *num); void lerNumero2(int *num); void mensagem(); void mesagem2(); void mensagem3(); void mensagem4(); Arquivo hash.c: # include <stdio.h> # include <stdlib.h> # include <windows.h> # include <time.h> # include <conio.h> # include "hash.h" /*funcaoHash recebe como parametro uma variavel do tipo inteiro(num), retorna a restra da divisao do valor dessa variavel pela tamanho da tabela*/ int funcaoHash(int num) { return(num%tam); } /*O procedimento inicializaHash recebe como parametro uma variavel do tipo Hash e sua funcao e que todas as posicoes da tab se tornem nulas*/ void inicializaHash(Hash tab) { int i; for(i = 0; i < tam; i++) { tab[i] = NULL; } } /*O procedimento insererHash recebe como parametro dois argumentos uma variavel do tipo Hash e outra do tipo num. Sua funcao e inserir os elementos na tabela atraveis da funcaoHash e caso esta posicao ja esteja preenchida, como colisao esta sendo adotado neste procedimento o encadeamento direto.*/ void insereHash(Hash tab, int num) { int i = 0; int chave = funcaoHash(num); Dados* aux = tab[chave]; while(aux != NULL) { if(aux->info == num) { break; } aux = aux->prox; } if(aux == NULL) { aux = (Dados*)malloc(sizeof(Dados)); aux->info = num; aux->prox = tab[chave]; tab[chave] = aux; } } /*O procedimento buscaHash recebe como parametro duas variaveis uma do tipo Hash(tab) e outra do tipo inteiro(num),A variavel tab tem como funcao passar a tabela e a variavel num tem como funcao determinar a posicao da tabela que o usuario deseja visualizar*/ void buscaHash(Hash tab,int num) { int pos = num; if(num > tam || num < 0) { printf("\nPosicao nao encontrada!"); return; }else { imprimeColisao(tab,pos); }} /*O procedimento imprimeHash recebe como parametro uma variavel do tipo Hash. Sua funcao e imprimir todos os elementos da variavel do tipo Hash*/ void imprimeHash(Hash tab) { int i = 0,cont = 0; for(i = 0; i < tam; i++) { if(tab[i] != NULL) { printf("\n %d",tab[i]->info); Dados* aux =tab[i]->prox; while(aux!=NULL) { printf(" -> %3d",aux->info); aux=aux->prox; } } } } /*O procedimento removeHash recebe como parametro uma variavel do tipo Hash e outra do tipo inteiro, a variavel do tipo Hash serve para termos acesso a tabela e a variavel do tipo inteiro serve para escolher a posicao que o usuario deseja visualizar, apos a visualizacao da chave, o usuario escolhe a informacao da chave que deseja eliminar*/ void removeHash(Hash tab, int num) { int pos = num; int ex ; if(num > tam) { printf("\nEsta posicao nao existe na tabela!"); }else{ if(tab[pos] == NULL) { printf("Esta chave esta vazia!"); }else { printf("\n\n\n"); imprimeColisao(tab,pos); printf("\n\nQual registro deseja apagar = "); scanf("%d",&ex); if(tab[pos]->info == ex) { if(tab[pos]->prox == NULL) { tab[pos] = NULL; return; } if(tab[pos]->prox != NULL) { tab[pos]->info = tab[pos]->prox->info; tab[pos]->prox = tab[pos]->prox->prox; return; } }else{ if(tab[pos]->info != ex) { if(tab[pos]->prox == NULL) { printf("\nRegistro nao encontrado!"); getch(); return; }else{ Dados* ant = NULL; Dados* aux = tab[pos]->prox; while(aux->prox != NULL && aux->info != ex) { ant = aux; aux = aux->prox; } if(aux->info != ex) { printf("\nRegistro nao encontrado!\n"); return; }else { if(ant == NULL) { tab[pos]->prox = aux->prox; }else{ ant->prox = aux->prox; } aux = NULL; free(aux); } } } } } } } /*O precedimento criarArquivo recebe como parametro uma variavel do tipo FILE*. Sua funcao é criar um arquivo, que futuramente será usado como recipiente para guardar os numero aleatorios.*/ void criarArquivo(FILE* arquivo) { arquivo = fopen("hash.txt", "r"); if(arquivo == NULL) { arquivo = fopen("hash.txt", "w"); fclose(arquivo); }else { return; } } /*O procedimento reescreveArquivo recebe como parametro uma variavel do tipo FILE*. Sua funcao é eliminar o arquivo anterior.*/ void reescreveArquivo(FILE* arquivo) { arquivo = fopen("hash.txt", "w"); fclose(arquivo); } /*O procedimento escreveArquivo recebe como parametro uma variavel do tipo FILE* e outra do tipo inteiro. A variavel do tipo FILE* fornece o acesso para o arquivo e a variavel do tipo inteiro sera o elemento que o usuario vai guardar no arquivo*/ void escreverArquivo(FILE* arquivo, int elemento) { arquivo = fopen("hash.txt", "a"); fprintf(arquivo,"%3d\n",elemento); fclose(arquivo); } /*A funcao carregaArquivo recebe como parametro o arquivo onde esta guardado todos as informacoes. Sua funcao e inserir na tabela Hash os elementos que estao no arquivo.*/ int carregaArquivo(Hash tab) { int elemento; FILE* arquivo; arquivo = fopen("hash.txt","r"); fseek(arquivo,0,SEEK_END); if(ftell(arquivo) == 0) { return 0; } fseek(arquivo,0,SEEK_SET); if(arquivo == NULL) { return 0; }else { while(!feof(arquivo)) { fscanf(arquivo,"%d",&elemento); insereHash(tab,elemento); } system("cls"); } fclose(arquivo); return 1; } /*O procedimento linhaAnimada tem como parametro duas variaveis do tipo inteiro uma sera o comprimento e a outra sera o caracter escolhido pelo usuario. Sua funcao é desenhar na tela os caracteres escolhidos pelo usuario com um certo delay*/ void linhaAnimada(int q, int a) { int j; for(j = 1; j <= q; j++) { _sleep(200); printf("%c",a); } } /*O procedimento linha é similar ao linhaAnimada, mais sem delay*/ void linha(int q, int a) { int j; for(j = 1; j <= q; j++) printf("%c",a); } /*O procedimento cor recebe como parametro uma variavel do tipo WORD. sua funcao é possibilitar que o programador modifique as cores do texto ou do fundo*/ void cor(WORD cor) { HANDLE SaidaSTD = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(SaidaSTD, cor); } /*O procedimento posicao tem como parametro duas variaveis do tipo inetiro . Sua funcao é possibilitar que o programador escolha a posicao na tela que deseja visualizar determinada instrucao.*/ void posicao(int x, int y) { HANDLE SaidaSTD = GetStdHandle(STD_OUTPUT_HANDLE); COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(SaidaSTD, coord); } /*O procedimento menuHash sera uma interface para o usuario visualizar e escolher suas opcoes*/ void menuHash(int *num) { system("cls"); cor(11);posicao(22,1);linha(1,201);linha(41,205);linha(1,187); cor(11);posicao(22,2);printf("\272");posicao(64,2);printf("\272"); cor(15);posicao(40,2);printf("HASH"); cor(11);posicao(22,3);linha(1,204);linha(41,205);linha(1,185); cor(11);posicao(22,4);printf("\272 1 \x1a Gerar numeros aleatoios\t\t\272"); cor(11);posicao(22,5);linha(1,204);linha(41,205),linha(1,185); cor(11);posicao(22,6);printf("\272 2 \x1a Inserir os numeros aleatorios \t\272"); cor(11);posicao(22,7);linha(1,204);linha(41,205),linha(1,185); cor(11);posicao(22,8);printf("\272 3 \x1a Buscar chave \t\t\t\272"); cor(11);posicao(22,9);linha(1,204);linha(41,205),linha(1,185); cor(11);posicao(22,10);printf("\272 4 \x1a Remover chave \t\t\t\272"); cor(11);posicao(22,11);linha(1,204);linha(41,205),linha(1,185); cor(11);posicao(22,12);printf("\272 5 \x1a Imprimir Hash \t\t\t\272"); cor(11);posicao(22,13);linha(1,204);linha(41,205),linha(1,185); cor(11);posicao(22,14);printf("\272 6 \x1a Menu Estatistica \t\t\272"); cor(11);posicao(22,15);linha(1,204);linha(41,205),linha(1,185); cor(11);posicao(22,16);printf("\272 7 \x1a Sair \t\t\t\t\272"); cor(11);posicao(22,17);linha(1,200);linha(41,205),linha(1,188); cor(15);posicao(1,1);printf("\nDigite uma opcao = ");scanf("%d",num); } /*O procedimento menuEstatistica sera uma interface para o usuario visualizar as e escolher uma das opcoes */ void menuEstatistica(int *num) { system("cls"); cor(11);posicao(10,1);linha(1,201);linha(53,205);linha(1,187); cor(11);posicao(10,2);printf("\272");posicao(64,2);printf("\272"); cor(10);posicao(30,2);printf("ESTATISTICAS"); cor(11);posicao(10,3);linha(1,204);linha(53,205);linha(1,185); cor(11);posicao(10,4);printf("\272 1 \x1a Porcentagem de preenchimento da tabela \t\t\272"); cor(11);posicao(10,5);linha(1,204);linha(53,205),linha(1,185); cor(11);posicao(10,6);printf("\272 2 \x1a Vizualizar as posicoes que ocorreram colisoes\t\272"); cor(11);posicao(10,7);linha(1,204);linha(53,205),linha(1,185); cor(11);posicao(10,8);printf("\272 3 \x1a imprimir determinada posicao\t\t\t\272"); cor(11);posicao(10,9);linha(1,204);linha(53,205),linha(1,185); cor(11);posicao(10,10);printf("\272 4 \x1a Visualizar quantidade de colisoes \t\t\272"); cor(11);posicao(10,11);linha(1,204);linha(53,205),linha(1,185); cor(11);posicao(10,12);printf("\272 5 \x1a Visualiar as posicoes vazias \t\t\t\272"); cor(11);posicao(10,13);linha(1,204);linha(53,205),linha(1,185); cor(11);posicao(10,14);printf("\272 0 \x1a Sair \t\t\t\272"); cor(11);posicao(10,15);linha(1,200);linha(53,205),linha(1,188); cor(15);posicao(9,16);printf("Digite uma opcao = ");scanf("%d",num); } /*A funcao porcentagemHash retorna a quantidade em procentagem da tabela que foi completada.*/ float porcentagemHash(Hash tab) { int i; float porcent = 0, cont = 0; for(i = 0; i < tam; i++) { if(tab[i] != NULL) { cont++; } } porcent = (cont*100)/tam; return(porcent); } /*O procedimento indiceColisao mostra as posicoes da tabela que ocorreram colisoes*/ void indiceColisao(Hash tab) { int i, cont = 0; posicao(25,1);printf("\nOcorreram colisoes nas posicoes\n"); for(i = 0 ; i< tam; i++) { if(tab[i] != NULL && tab[i]->prox) { printf("%d\t",i); } } return; } /*A fucao quantidadeColisao retorna em variavel do tipo inteiro total de colisoes que ocorreram na tabela*/ int quantidadeColisao(Hash tab) { int i, cont = 0; for(i = 0; i < tam; i++) { Dados* aux = tab[i]; if(aux != NULL) { while(aux->prox != NULL) { cont++; aux = aux->prox; } } } return cont; } /*O procedimento posicaoVazias mostra todas as posicoes que apos a insercao continuam nulas.*/ void posicoesVazias(Hash tab) { int i, cont = 0; posicao(25,1);printf("Posicoes Vazias\n"); for(i = 0; i < tam; i++) { if(tab[i] == NULL) { printf("%d\t",i); cont++; } } printf("\nTotal de posicoes vazias = %d",cont); } /*O procedimento imprimeColisaon mostra uma posicao e todas as suas colisoes.*/ void imprimeColisao(Hash tab, int pos) { Dados* aux = tab[pos]; if(aux == NULL) { printf("Esta posicao esta vazia!"); return; }else { if(aux != NULL) { printf("%3d",aux->info); while(aux->prox != NULL) { printf(" -> %d",aux->prox->info); aux = aux->prox; } } } } /*O procedimento numeroAleatorio gera 675 numeros no intervalo 2000 >= X <= 8200 e os armazena no arquivo*/ void numeroAleatorio() { int numero,cont = 0; FILE* arquivo; srand(time(NULL)); while(cont != 675) { numero = (rand()%6200)+2000; escreverArquivo(arquivo, numero); cont++; } } void lerNumero(int *num) { system("cls"); printf("\nDigite a posicao do elemento que deseja verificar = "); scanf("%d",num); } void lerNumero1(int *num) { system("cls"); printf("\nDigite a posicao do elemento que deseja excluir = "); scanf("%d",num); } void lerNumero2(int *num) { system("cls"); printf("Digite a posicao que desejar verificar = "); scanf("%d",num); } void mensagem() { system("cls"); cor(11);posicao(20,1);linha(1,201);linha(41,205);linha(1,187); posicao(20,2);printf("\272");posicao(62,2);printf("\272"); posicao(20,3);linha(1,200);linha(41,205);linha(1,188); cor(10);posicao(26,2);printf("GERANDO NUMEROS ALEATORIOS"); cor(12);posicao(21,2);linhaAnimada(41,219); cor(202);posicao(36,2);printf("CONCLUIDO"); getch(); cor(1|2|4); } void mesagem2() { system("cls"); cor(11);posicao(20,1);linha(1,201);linha(41,205);linha(1,187); posicao(20,2);printf("\272");posicao(62,2);printf("\272"); posicao(20,3);linha(1,200);linha(41,205);linha(1,188); cor(10);posicao(26,2);printf("TABELA HASH CRIADA COM SUCESSO"); getch();; } void mensagem3() { system("cls"); cor(11);posicao(20,1);linha(1,201);linha(41,205);linha(1,187); posicao(20,2);printf("\272");posicao(62,2);printf("\272"); posicao(20,3);linha(1,200);linha(41,205);linha(1,188); cor(10);posicao(24,2);printf("OS NUMEROS AINDA NAO FORAM GERADOS"); getch();; } void mensagem4() { system("cls"); cor(11);posicao(20,1);linha(1,201);linha(41,205);linha(1,187); posicao(20,2);printf("\272");posicao(62,2);printf("\272"); posicao(20,3);linha(1,200);linha(41,205);linha(1,188); cor(10);posicao(30,2);printf("TABELA NAO FOI CRIADA"); getch(); Arquivo hash.cpp: # include "hash.c" main() { Hash tab; int num, elemento, op,cont = 0, conti = 0; FILE* arquivo; criarArquivo(arquivo); while(num != 8) { menuHash(&num); switch(num) { case 1: if(cont > 0) { system("cls"); printf("\nOs Numeros Aleatorios ja foram gerados!\n"); }else{ cont++; inicializaHash(tab); reescreveArquivo(arquivo); numeroAleatorio(); mensagem(); } break; case 2: if(cont > 0) { conti++; carregaArquivo(tab); mesagem2(); }else{ mensagem3(); } break; case 3: if(conti > 0) { system("cls"); lerNumero(&elemento); buscaHash(tab,elemento); getch(); }else{ mensagem4(); } break; case 4: if(conti > 0) { system("cls"); lerNumero1(&elemento); removeHash(tab,elemento); getch(); }else{ mensagem4(); } break; case 5: if(conti > 0) { system("cls"); imprimeHash(tab); }else{ mensagem4(); } getch(); break; case 6: op = -1; if(conti > 0) { while(op != 0) { menuEstatistica(&op); switch(op) { case 0: system("cls"); break; case 1: system("cls"); posicao(25,3);printf("%g%% da tabela foi preenchida!\n",porcentagemHash(tab)); getch(); break; case 2: system("cls"); indiceColisao(tab); getch(); break; case 3: system("cls"); lerNumero2(&op); imprimeColisao(tab,op); getch(); break; case 4: system("cls"); posicao(25,3);printf("Total de colisoes = %d",quantidadeColisao(tab)); getch(); break; case 5: system("cls"); posicoesVazias(tab); getch(); break; default: system("cls"); printf("\nOpcao invalida!"); getch(); break; } system("cls"); } }else{ mensagem4(); } break; case 7: exit(0); default: system("cls"); printf("\nOpcao invalida!\n"); getch(); break; } system("cls"); } }
Árvore AVL, usando arquivos para armazenamento de dados
Emulador de Chip8 (com gráficos)
Rotina para controle de portas paralelas em C. (biblioteca LP.h)
Nenhum comentário foi encontrado.
Enviar mensagem ao usuário trabalhando com as opções do php.ini
Meu Fork do Plugin de Integração do CVS para o KDevelop
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Compartilhamento de Rede com samba em modo Público/Anônimo de forma simples, rápido e fácil
Cups: Mapear/listar todas as impressoras de outro Servidor CUPS de forma rápida e fácil
Criando uma VPC na AWS via CLI
Olá quando fui olhar as logs achei um erro bem estranho chamado: End o... (0)
Servidor said: 530 5.7.0 Must issue a STARTTLS command first (in r... (3)
Impressora Bematech MP4200TH rorando com a distribuição Zorin OS (0)
como fazer overclock na ram? (7)
Existe algum problema de atualizar uma versão lts para uma versão não ... (3)