Advertisement
Liba

finallyooooo.c

Jul 22nd, 2014
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 33.99 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5.  
  6. #include "estruturas.h"
  7.  
  8. /* Segura o valor do último voo adicionado, auxiliando na escrita dos dados dos passageiros no arquivo.
  9.  * É setada como " " propositalmente, para que possa ser corretamente utilizada na função save_pas, que
  10.  * salva as informações dos passageiros inseridos em um arquivo txt. */
  11. char atual_Plane_Pas[16] = " ";
  12. long number_of_Pages; /* Variável auxiliar que guarda o número de páginas de voo contidas na árvore B. */
  13. int number_of_Planes; /* Variável auxiliar que guarda o número de voos contidos no arquivo de dados do mesmo */
  14. static int auxFatBal = 0;   /*Auxiliar de fator de balanceamento */
  15.  
  16. /* Método de busca de um passageiro na sua árvore AVL */
  17. struct Nodo* search_Pas(char key_Pas[], struct Nodo* pNodo) {
  18.     /* Enquanto o endereço for diferente de nulo e não tenha encontrado o passageiro solicitado */
  19.     while((pNodo != NULL) && (strcmp(pNodo->info.pass, key_Pas))) {
  20.         /* se a chave procurada for menor que o nó comparado, vai para seu filho a esquerda (lado onde estará a chave procurada, se ela existir) */
  21.         if(strcmp(pNodo->info.pass, key_Pas) > 0)
  22.             pNodo = pNodo->pLeft;
  23.         else /* se a chave procurada for maior que o nó comparado, vai para seu filho a direita */
  24.             pNodo = pNodo->pRight;
  25.     }
  26.    
  27.     if (pNodo == NULL) /* caso o passageiro buscado não esteja na árvore AVL */
  28.         printf ("ERRO\n");
  29.     return pNodo; /* Irá retornar NULL (valor inicial do pNodo), caso nenhum passageiro seja encontrado */
  30. }
  31.  
  32. /* Método responsável por balancear a árvore no sentido horário */
  33. void balance_Horario(struct Nodo** pNodo) {
  34.     struct Nodo* pAux = (*pNodo)->pLeft; /* Nodo auxiliar recebe o filho a esquerda no nodo recebido. */
  35.  
  36.     if(pAux->factor_Balance == 1) /* Se o fator de balanceamento do nodo auxiliar for igual a um. */
  37.         balance_AntiHorario(&(*pNodo)->pLeft); /* Chama a função balancear anti horário passando o filho a esquerda do nodo atual. */
  38.  
  39.     pAux = (*pNodo)->pLeft; /* Nodo auxiliar recebe o filho a esquerda no nodo recebido. */
  40.  
  41.     if(pAux->factor_Balance == -1 || pAux->factor_Balance == 0) { /* Se o fator de balanceamento do auxiliar for igual a menos um ou zero. */
  42.         (*pNodo)->pLeft = pAux->pRight; /* O filho a esquerda do nodo recebe o filho a direita da auxiliar. */
  43.         pAux->pRight = (*pNodo); /* O filho a direita do auxiliar recebe o nodo. */
  44.         (*pNodo)->factor_Balance = 0; /* O fator de balanceamento do nodo recebe zero. */
  45.         (*pNodo) = pAux; /* O nodo recebe o auxiliar. */
  46.     }
  47.  
  48.     (*pNodo)->factor_Balance = 0; /* O fator de balanceamento do nodo recebe zero. */
  49. }
  50.  
  51. /* Método responsável por balancear a árvore no sentido anti-horário */
  52. void balance_AntiHorario(struct Nodo** pNodo) {
  53.     struct Nodo* pAux = (*pNodo)->pRight; /* Nodo auxiliar recebe o filho a direita no nodo recebido. */
  54.  
  55.     if(pAux->factor_Balance == -1) /* Se o fator de balanceamento do nodo auxiliar for igual a um. */
  56.         balance_AntiHorario(&(*pNodo)->pRight); /* Chama a função balancear horário passando o filho a direita do nodo atual. */
  57.  
  58.     pAux = (*pNodo)->pRight; /* Nodo auxiliar recebe o filho a direita no nodo recebido. */
  59.  
  60.     if(pAux->factor_Balance == 1 || pAux->factor_Balance == 0) { /* Se o fator de balanceamento do auxiliar for igual a menos um ou zero. */
  61.         (*pNodo)->pRight = pAux->pLeft; /* O filho a direita do nodo recebe o filho a esquerda da auxiliar. */
  62.         pAux->pLeft = (*pNodo); /* O filho a esquerda do auxiliar recebe o nodo. */
  63.         (*pNodo)->factor_Balance = 0; /* O fator de balanceamento do nodo recebe zero. */
  64.         (*pNodo) = pAux; /* O nodo recebe o auxiliar. */
  65.     }
  66.  
  67.     (*pNodo)->factor_Balance = 0; /* O fator de balanceamento do nodo recebe zero. */
  68. }
  69.  
  70. /* método responsável por separar as informações da string contendo os dados do passageiro, para que possam ser utilizadas */
  71. struct Passager convert_Data (char data[]) {
  72.     struct Passager data_Struct; /* variável que armazenará todos os dados separados (será retornado posteriormente) */
  73.     /* encontra primeira informação, que é o código voo */
  74.     char auxCodVoo[16] = " "; /* variável auxiliar que recebe o código do voo (que tem o tamanho 15) */
  75.     int i = 0;
  76.     while (data[i] != '@') { /* o código do voo estará localizado antes do primeiro delimitador (@) da string */
  77.         auxCodVoo[i] = data[i]; /* preenche a variável auxiliar com os primeiros 15 caracteres, que é o código do voo */
  78.         i++;
  79.     }
  80.     strcpy (data_Struct.code_Plane, auxCodVoo); /* copia codigo do voo para seu respectivo campo */
  81.    
  82.     char auxPas[11] = " "; /* variável auxiliar que recebe o passaporte (que tem o tamanho 10) */
  83.     i = i+1; /* posição do primeiro caracter depois do primeiro @ */
  84.     int j = 0; /* controla as posições da variável auxiliar, iniciando com valor 0 (primeira posição) */
  85.    
  86.     /* encontra segunda informação, que é o passaporte */
  87.     while (data[i] != '@') {
  88.         auxPas[j] = data[i];
  89.         i++;
  90.         j++;
  91.     }
  92.     strcpy (data_Struct.pass, auxPas); /* copia passaporte para seu respectivo campo */
  93.    
  94.     char auxNome[101] = " "; /* variável auxiliar que recebe o nome (que tem o tamanho máximo de 100 caracteres) */
  95.     i = i+1; /* posição do primeiro caracter depois do segundo @ */
  96.     j = 0; /* controle da variável auxiliar */
  97.    
  98.     /* encontra terceira informação, que é o nome */
  99.     while (data[i] != '@') {
  100.         auxNome[j] = data[i];
  101.         i++;
  102.         j++;
  103.     }
  104.     strcpy (data_Struct.name, auxNome); /* copia nome para seu respectivo campo */
  105.    
  106.     char auxPol[4] = " "; /* variável auxiliar que recebe a poltrona (que tem o tamanho 3) */
  107.     i = i+1; /* posição do primeiro caracter depois do terceiro @ */
  108.     j = 0;
  109.    
  110.     /* encontra quarta informação, que é o poltrona */
  111.     while (j < 4) {
  112.         auxPol[j] = data[i];
  113.         i++;
  114.         j++;
  115.     }
  116.     strcpy (data_Struct.chair, auxPol); /* copia poltrona para seu respectivo campo */
  117.    
  118.     return data_Struct; /* retorna a estrutura corretamente preenchida */
  119. }
  120.  
  121. /* Método responsável por armazenar as informações dos passageiros em um arquivo txt */
  122. void save_Pas (char data[]) {  
  123.     struct Passager data_Struct = convert_Data (data); /* estrutura que armazena as informações do novo passageiro inserido */
  124.  
  125.     FILE *passager; /* variável do tipo FILE, para abrir (ou criar) arquivo texto de passageiros */
  126.     passager = fopen ("passager.txt", "r+"); /* tenta ler arquivo texto de passageiro */
  127.     if(passager == NULL) { /*Se o arquivo não existir */
  128.         passager = fopen ("passager.txt", "w+"); /* cria novo arquivo txt para que possa ser armazenado os dados do passageiro */
  129.     }
  130.    
  131.     fseek(passager, 0, SEEK_END); /* Move o cursor do arquivo para o endereço da página que o novo passageiro será incluido. */
  132.     if (!strcmp (atual_Plane_Pas, " ") || strcmp (atual_Plane_Pas, data_Struct.code_Plane)) { /* Caso seja um voo diferente */
  133.         fprintf(passager, "#%s#", data_Struct.code_Plane); /* preenche parte do arquivo com o codigo do voo, com os caracteres delimitadores # */
  134.         /* define a variavel global atual_Plane_Pas como o código do novo voo inserido, desta forma,
  135.          * caso haja mais passageiros deste mesmo voo, o codigo do voo será inserido no arquivo apenas uma vez. */
  136.         strcpy (atual_Plane_Pas, data_Struct.code_Plane);
  137.     }
  138.     /* Escreve as informações do passageiro, delimitados pelo caracter @, no arquivo */
  139.     fprintf(passager, "%s@%s@%s@", data_Struct.pass, data_Struct.name, data_Struct.chair);
  140.     fclose (passager); /* fecha arquivo txt de passageiros */
  141.  
  142. }
  143.  
  144. /* Método responsável pela criação da árvore AVL de passageiros de um determinado voo */
  145. int insert_Pas (char data[], struct Nodo** pNodo) {
  146.     struct Passager data_Struct = convert_Data (data); /* converte string extraida no arquivo, para que seja possível utilizar o código do passageiro */
  147.    
  148.     /* pNodo se inicia com valor da raiz. Se não tiver raiz, ele será nulo inicialmente,
  149.      * caso contrário, chama recursivamente até achar posição nula. */
  150.     if((*pNodo) == NULL) {
  151.         (*pNodo) = (struct Nodo*)malloc(sizeof(struct Nodo));
  152.         (*pNodo)->info = data_Struct;
  153.         (*pNodo)->pLeft = NULL;
  154.         (*pNodo)->pRight = NULL;
  155.         (*pNodo)->factor_Balance = 0;
  156.                
  157.         printf ("SUCESSO\n");
  158.         /* verifica balanceamento da árvore */
  159.         if(auxFatBal == 1)
  160.             return 1;
  161.         else
  162.             if(auxFatBal == 2)
  163.                 return -1;
  164.     }
  165.     else {
  166.         /* Caso o código do novo passageiro inserido seja maior que o nó pai */
  167.         if(strcmp(data_Struct.pass, (*pNodo)->info.pass) > 0) {
  168.             auxFatBal = 1;
  169.             (*pNodo)->factor_Balance += insert_Pas(data, &(*pNodo)->pRight); /* chama a funação recursivamente, indo para o lado direito (maior) do provisório nó pai */
  170.  
  171.             if((*pNodo)->pRight->factor_Balance != 0) {
  172.                 (*pNodo)->factor_Balance ++; /* como o nó receberá um novo filho, cresce seu fator de balanceamento */
  173.  
  174.                 if( (*pNodo)->factor_Balance > 1) /* verifica se é necessário fazer o balanceamento da árvore */
  175.                     balance_AntiHorario(&(*pNodo));
  176.             }
  177.  
  178.         }
  179.         else {
  180.             /* Caso o código do novo passageiro inserido seja menor que o nó pai */
  181.             if(strcmp(data_Struct.pass, (*pNodo)->info.pass) < 0) {
  182.                 auxFatBal = 2;
  183.                 /* chama a funação recursivamente, indo para o lado esquerdo (menor) do provisório nó pai */
  184.                 (*pNodo)->factor_Balance += insert_Pas(data, &(*pNodo)->pLeft);
  185.  
  186.                 if((*pNodo)->pLeft->factor_Balance != 0) {
  187.                     /* incrementa fator balanceamento do lado esquerdo da árvore (que é reprensentado por um número negativo,
  188.                      * permitindo o cálculo com o lado direito que é um número positivo) */
  189.                     (*pNodo)->factor_Balance --;
  190.  
  191.                     if( (*pNodo)->factor_Balance < -1) { /* verifica se é necessário fazer o balanceamento da árvore */
  192.                         balance_Horario(&(*pNodo));
  193.  
  194.                     }
  195.                 }
  196.             }
  197.         }
  198.     }
  199.  
  200.     return 0;
  201. }
  202.  
  203. /* Método responsável pela remoção de um passageiro na árvore AVL */
  204. int remove_Pas(char key_Pas[], struct Nodo** pNodo) {
  205.  
  206.     if(strcmp(key_Pas, (*pNodo)->info.pass) > 0) { /* Se a chave para remover for maior que a chave do nodo atual. */
  207.         auxFatBal = 2; /* Auxiliar de fator de balanceamento recebe 2. */
  208.         (*pNodo)->factor_Balance += remove_Pas(key_Pas, &(*pNodo)->pRight); /* O fator de balanceamento do nodo atual é acrescentado o valor do retorno
  209.                                                                                da chamada da função recursivamente da chave no nodo direito. */
  210.         if((*pNodo)->pLeft != NULL && (*pNodo)->pLeft->factor_Balance == 0) { /* Se o nodo tiver filho a esquerda com fator de balanceamento igual a zero. */
  211.             (*pNodo)->factor_Balance --; /* O fator de balanceamento do nodo é decrementado. */
  212.  
  213.             if( (*pNodo)->factor_Balance < -1) /* Se o fator de balanceamento do nodo for menor que menos 1. */
  214.                 balance_Horario(&(*pNodo)); /* Chama a função balancear no sentido horário no nodo. */
  215.  
  216.         }
  217.     }
  218.     else {
  219.         if(strcmp(key_Pas, (*pNodo)->info.pass) < 0) { /* Se a chave para remover for menor que a chave do nodo atual. */
  220.             auxFatBal = 1; /* Auxiliar de fator de balanceamento recebe 2. */
  221.             (*pNodo)->factor_Balance += remove_Pas(key_Pas, &(*pNodo)->pLeft); /* O fator de balanceamento do nodo atual é acrescentado o valor do retorno
  222.                                                                                da chamada da função recursivamente da chave no nodo esquerdo. */
  223.  
  224.             if((*pNodo)->pRight != NULL && (*pNodo)->pRight->factor_Balance == 0) { /* Se o nodo tiver filho a direita com fator de balanceamento igual a zero. */
  225.                 (*pNodo)->factor_Balance ++; /* O fator de balanceamento do nodo é acrementado. */
  226.  
  227.                 if( (*pNodo)->factor_Balance > 1) /* Se o fator de balanceamento do nodo for maior que 1. */
  228.                     balance_Horario(&(*pNodo)); /* Chama a função balancear no sentido anti horário no nodo. */
  229.  
  230.             }
  231.         }
  232.         else { /* A chave foi encontrada para ser removida. */
  233.             if((*pNodo)->pRight == NULL && (*pNodo)->pLeft == NULL) { /* Se o nodo não tiver filhos. */
  234.                 free(*pNodo); /* Limpa o nodo da memória. */
  235.                 (*pNodo) = NULL; /* Nodo recebe vazio. */
  236.  
  237.                 printf ("SUCESSO\n"); /* Feedback. */
  238.  
  239.                 if(auxFatBal == 1) /* Se a auxiliar é igual a 1. */
  240.                     return 1;
  241.  
  242.                 else
  243.                     if(auxFatBal == 2) /* Se a auxiliar é igual a 2. */
  244.                         return -1;
  245.             }
  246.             else if((*pNodo)->pLeft == NULL) { /* Se o nodo tiver apenas filhos a direita. */
  247.                 struct Nodo* pAux = (*pNodo); /* Auxiliar recebe o nodo. */
  248.                 (*pNodo) = (*pNodo)->pRight; /* Nodo recebe seu filho a direita. */
  249.                 free(pAux); /* Limpa a auxiliar da memoria. */
  250.                 pAux = NULL; /* Auxiliar recebe vazio. */
  251.  
  252.                 printf ("SUCESSO\n"); /* Feedback. */
  253.  
  254.                 if(auxFatBal == 1) /* Se a auxiliar é igual a 1. */
  255.                     return 1;
  256.  
  257.                 else
  258.                     if(auxFatBal == 2) /* Se a auxiliar é igual a 2. */
  259.                         return -1;
  260.                 }
  261.                 else if((*pNodo)->pRight == NULL) { /* Se o nodo tiver apenas filhos a esquerda. */
  262.                     struct Nodo* pAux = (*pNodo); /* Auxiliar recebe o nodo. */
  263.                     (*pNodo) = (*pNodo)->pLeft; /* Nodo recebe seu filho a esquerda. */
  264.                     free(pAux); /* Limpa a auxiliar da memoria. */
  265.                     pAux = NULL; /* Auxiliar recebe vazio. */
  266.  
  267.                     printf ("SUCESSO\n"); /* Feedback. */
  268.  
  269.                     if(auxFatBal == 1) /* Se a auxiliar é igual a 1. */
  270.                         return 1;
  271.  
  272.                     else
  273.                     if(auxFatBal == 2) /* Se a auxiliar é igual a 2. */
  274.                         return -1;
  275.                 }
  276.                 else { /* Caso o nodo tenha filho direito e esquerdo. */
  277.                     (*pNodo)->info = search_Biggest_Left((*pNodo)->pLeft)->info; /* As informações do nodo recebe as informações do maior nodo a esquerda. */
  278.                     return remove_Pas(key_Pas, &(*pNodo)->pLeft); /* Chama a função remover recursivamente. */
  279.                 }
  280.             }
  281.         }
  282.     return 0;
  283. }
  284.  
  285. struct Nodo* search_Biggest_Left(struct Nodo* pNodo) {
  286.  
  287.     while(pNodo->pRight != NULL)
  288.         pNodo = pNodo->pRight;
  289.  
  290.     return pNodo;
  291. }
  292.  
  293. void cut_Tree (struct Nodo* pNodo) {
  294.  
  295.     if (pNodo->pLeft == NULL && pNodo->pRight == NULL)
  296.         free (pNodo);
  297.  
  298.     if (pNodo->pLeft != NULL)
  299.         cut_Tree (pNodo->pLeft);
  300.  
  301.     if (pNodo->pRight != NULL)
  302.         cut_Tree (pNodo->pRight);
  303.  
  304. }
  305.  
  306. void save_Page(FILE *p, long RRN_Page, struct Page *page) {
  307.     if(p != NULL) { /*Se a tentativa de abrir o arquivo foi um sucesso. */
  308.         fseek(p, RRN_Page, SEEK_SET); /* Move o cursor do arquivo para o endereço da página. */
  309.         fwrite(page, sizeof(struct Page), 1, p); /* Escreve a página passada no arquivo. */
  310.     }
  311.     else {
  312.         printf("ERRO\n");
  313.     }
  314. }
  315.  
  316. void load_Page(FILE *p, long RRN_Page, struct Page *page) {
  317.     if (p != NULL) { /* Se a tentativa de abrir o arquivo foi um sucesso. */
  318.         fseek(p, RRN_Page, SEEK_SET); /* Move o cursor do arquivo para o endereço da página. */
  319.         fread(page, sizeof(struct Page), 1, p); /* Carrega a página do arquivo para a estrutura page. */
  320.     }
  321.     else {
  322.         printf("ERRO\n");
  323.     }
  324. }
  325.  
  326. void createNewPage(struct Page *page) {
  327.     page->num_Plane = 0;
  328.     int i;
  329.     for(i = 0; i < MAX_INDEX + 1; i++) {
  330.         if( i < MAX_INDEX) {
  331.             strcpy(page->planes[i].key_Plane, "####");
  332.             page->planes[i].RRN_Plane = -1;
  333.         }
  334.         page->RRN_Son[i] = -1;
  335.     }
  336. }
  337. void update_Root(long new_Root) {
  338.     FILE *p;
  339.     p = fopen("index.dat", "wb");
  340.     if(p != NULL) {
  341.         fseek(p, 0, 0);
  342.         fwrite(&new_Root, sizeof(long), 1, p);
  343.     }
  344.     else {
  345.         printf("ERRO\n");
  346.     }
  347.     fclose(p);
  348. }
  349.  
  350. long load_RNN_Root(FILE *p) {
  351.     long root;
  352.     fseek(p, 0, 0); /* Mover o cursor para o início do arquivo. Que é onde o RRN da raiz se localiza. */
  353.     fread(&root, sizeof(long), 1, p); /* Carrega o RRN da raiz na variável root. */
  354.     return root; /* Retorna a raiz encontrada. */
  355. }
  356.  
  357. void split(struct Page *atual_Page, struct Page *new_Page, struct Index promoter, long right_Son_Page) {
  358.     struct Index planesSplit[MAX_INDEX + 1]; /* Vetor auxiliar. */
  359.     long RRNSplit[MAX_INDEX + 1]; /* Vetor auxiliar. */
  360.    
  361.     int i = 0; /* Indice para começar a percorrer/preencher os vetores auxiliares. */
  362.     while(strcmp(promoter.key_Plane, atual_Page->planes[i].key_Plane) > 0)
  363.     { /* Enquanto o indice a ser inserido for maior do que o na posição i da página atual. */
  364.         RRNSplit[i] = atual_Page->RRN_Son[i]; /* Insere um filho da página atual no vetor auxiliar. */
  365.         planesSplit[i] = atual_Page->planes[i]; /* Insere um indice da página atual no vetor auxiliar. */
  366.         i++; /* Acrescimo do indice. */
  367.     }
  368.     RRNSplit[i] = atual_Page->RRN_Son[i]; /* Insere um filho da página atual no vetor auxiliar. */
  369.     planesSplit[i] = promoter; /* Insere o novo indice no vetor auxiliar. */
  370.     i++; /* Acrescimo do indice. */
  371.     RRNSplit[i] = right_Son_Page; /* Insere um filho a direita no vetor auxiliar. */
  372.     while(i < MAX_INDEX + 1) { /* Enquanto o indice for menor que o número máximo de index mais um.  */
  373.         RRNSplit[i + 1] = atual_Page->RRN_Son[i-1]; /* Insere um filho da página atual no vetor auxiliar. */
  374.         planesSplit[i] = atual_Page->planes[i-1]; /* Insere um indice da página atual no vetor auxiliar. */       
  375.         i++; /* Acrescimo do indice. */
  376.     }
  377.  
  378.  
  379.     /* Agora que já está tudo no vetor auxiliar, vamos passar para as duas páginas. */
  380.    
  381.     atual_Page->num_Plane = 0; /* "Esvaziando a página para começar a colocar os indices. */
  382.     new_Page->num_Plane = 0; /* "Esvaziando a página para começar a colocar os indices. */
  383.     createNewPage(atual_Page); /* Inicializando a página atual. */
  384.     createNewPage(new_Page); /* Inicializando a nova página. */
  385.  
  386.     int pos_Promoter = floor((MAX_INDEX + 1) / 2); /* Calculando em qual posição do vetor está o indice que deve ser promovido. */
  387.     promoter = planesSplit[pos_Promoter]; /* O promovido é buscado do vetor auxiliar. */
  388.  
  389.        
  390.     for(i = 0; i < pos_Promoter; i++) { /* Enquanto o indice for menor que a posição da chave que foi promovida. */
  391.         atual_Page->num_Plane ++; /* Acrescenta um na quantidade de voos da página. */
  392.         atual_Page->planes[i] = planesSplit[i]; /* Chave i da página recebe a chave i do vetor auxiliar. */
  393.         atual_Page->RRN_Son[i] = RRNSplit[i]; /* Filho i da página recebe o filho i do vetor auxiliar. */
  394.     }
  395.     atual_Page->RRN_Son[i] = RRNSplit[i]; /* Filho i da página recebe o filho i do vetor auxiliar. */
  396.     i++; /* Acrescimo do indice. */
  397.     for(; i < MAX_INDEX + 1; i++) { /* ENquanto o indice for menor que a quantidade máxima de chaves em uma página mais um. */
  398.         new_Page->num_Plane ++; /* Acrescenta um na quantidade de voos da página. */
  399.         new_Page->planes[i - pos_Promoter - 1] = planesSplit[i];
  400.         new_Page->RRN_Son[i - pos_Promoter - 1] = RRNSplit[i-1];
  401.     }
  402.    
  403.     new_Page->RRN_Son[i - pos_Promoter - 1] = RRNSplit[i - 1];
  404.  
  405. }
  406.  
  407. void save_Plane (char data[]) {
  408.            
  409.     struct Plane plane;
  410.     int i = 0;
  411.    
  412.     /* Separando a string com as informacoes do voo
  413.      * (todos são de tamanho fixo, o que justifica o
  414.      * valor utilizado em cada for) */
  415.     char cod1[15];
  416.     while (i < 15) {
  417.         cod1[i] = data[i];
  418.         i++;
  419.     }
  420.     strcpy(plane.code_Plane, cod1);  /* codigo voo */
  421.    
  422.     char cod2[4];
  423.     for(i = 0; i < 3; i++) {
  424.         cod2[i] = data[i + 16];
  425.     }
  426.     strcpy(plane.arrival_Airport, cod2); /* aeroporto partida */
  427.    
  428.     char cod3[4];
  429.     for(i = 0; i < 3; i++) {
  430.         cod3[i] = data[i + 20];
  431.     }
  432.     strcpy(plane.dest_Airport, cod3);  /* aeroporto chegada */
  433.    
  434.     char cod4[5];
  435.     for(i = 0; i < 5; i++) {
  436.         cod4[i] = data[i + 24];
  437.     }      
  438.     strcpy(plane.plane_Time, cod4); /* horario */
  439.    
  440.     char cod5[3];
  441.     for(i = 0; i < 2; i++) {
  442.         cod5[i] = data[i + 30];
  443.     }                                  
  444.     strcpy(plane.enterprise, cod5); /* companhia aerea */
  445.    
  446.     FILE *p;
  447.     p = fopen ("data.dat", "wb");
  448.     if(p != NULL) { /*Se a tentativa de abrir o arquivo foi um sucesso. */
  449.         fseek(p, 1, SEEK_END); /* Move o cursor do arquivo para o endereço da página. */
  450.         fwrite(&plane, sizeof(struct Plane), 1, p); /* Escreve a página passada no arquivo. */
  451.     }
  452.     else {
  453.         printf("ERRO\n");
  454.     }
  455.     fclose (p);  
  456. }
  457.  
  458. int insert_Plane(FILE *p, long RRN_Atual_Page, struct Index key_to_Insert, char data[], struct Index **promoter, long **right_Son_Page) {
  459.     strcpy (atual_Plane_Pas, " "); /* Novo voo (no arquivo do passageiro) */
  460.     struct Page atual_Page; /* Página atual. */
  461.     struct Page new_Page; /* Nova página caso precise quando for chamado o split. */
  462.     int value_Return;
  463.    
  464.     if(RRN_Atual_Page > -1) { /* Se a página existe. */
  465.         load_Page(p, RRN_Atual_Page, &atual_Page); /* Carregar a página do disco para a estrutura atual_Page. */
  466.         int pos = atual_Page.num_Plane; /* Variavel po é inicializada com o número de voos na página. */
  467.         int i = 0; /* Indice. */
  468.         while( i < atual_Page.num_Plane) { /* Enquanto o indice for menor que o número de voos na página. */
  469.             if(strcmp(key_to_Insert.key_Plane, atual_Page.planes[i].key_Plane) == 0) { /* Se a chave a ser inserida é igual
  470.                                                                                           a chave na posição i da página.   */
  471.                 printf("ERRO\n"); /* Feedback. */
  472.                 return -1; /* Não foi possível a inserção. */
  473.             }
  474.            
  475.             if(strcmp(key_to_Insert.key_Plane, atual_Page.planes[i].key_Plane) < 0) { /* Se a chave a ser inserida é menor
  476.                                                                                          do que a chave na posição i da página.
  477.                                                                                          Ou seja, a chave deveria estar lá.    */
  478.                 pos = i; /* Posição recebe o indice. */
  479.                 i = MAX_INDEX; /* Terminando o while para pegar a posição exata. */
  480.             }
  481.             i++; /* Acrescimo do indice. */
  482.         }
  483.         value_Return = insert_Plane(p, atual_Page.RRN_Son[pos], key_to_Insert, data, promoter, right_Son_Page); /* Chama a função inserir na página do filho na posição que deveria estar. */
  484.         if(value_Return < 2) { /* Se o retorno for não promoção ou erro */
  485.             return value_Return; /* Repassa o valor do retorno. */
  486.         }
  487.         else {  /* Se o retorno for promoção. */     
  488.             if(atual_Page.num_Plane < MAX_INDEX) { /* Se tem espaço para adicionar outro índice na página. */
  489.                 atual_Page.num_Plane ++; /* Aumenta o número de voos na página. */
  490.                 if(pos == atual_Page.num_Plane - 1) { /* Se o elemento deve ser inserido na última posição livre. */
  491.                     atual_Page.planes[atual_Page.num_Plane - 1] = **promoter; /* O voo da página recebe o promovido. */
  492.                     atual_Page.RRN_Son[atual_Page.num_Plane] = **right_Son_Page; /* O filho a direita do voo adicionado recebe o filho a direita do promovido. */
  493.                     save_Page(p, RRN_Atual_Page, &atual_Page); /* Salva a página atual. */
  494.                 }
  495.                 else {  /* Se o elemento não será inserido na última posição livre. */
  496.                     int j = atual_Page.num_Plane - 1; /* O indice j recebe a quantidade de voos na página atual menos 1. */
  497.                     while(j > pos) /* Enquanto o indice for maior que a posição que o elemento deve ser inserido. */
  498.                     {  /* Ordena a página. */
  499.                         atual_Page.planes[j] = atual_Page.planes[j-1];  /* Arrasta um voo para frente. */
  500.                         atual_Page.RRN_Son[j] = atual_Page.RRN_Son[j-1]; /* Arrasta um filho para frente. */
  501.                         j--; /* Decrescimo do indice. */
  502.                     }
  503.                     atual_Page.planes[j] = **promoter; /* A posição que ele devia ocupar recebe o promovido. */
  504.                     atual_Page.RRN_Son[j+1] = **right_Son_Page; /* O filho a direita do voo inserido recebe o filho a direita do promovido. */
  505.                     save_Page(p, RRN_Atual_Page, &atual_Page); /* Salva a página atual. */
  506.                 }
  507.                 return 1; /* Retorna não promoção. */
  508.             }
  509.             else { /* Se não tem espaço para adicionar um novo elemento na página. */
  510.                 split(&atual_Page, &new_Page, **promoter, **right_Son_Page); /* Chama a função split passando todos os parâmetros necessários.*/
  511.                 long free_Pos = sizeof(long) + (number_of_Pages * sizeof(struct Page)); /* Posição vaga para inserir nova página */
  512.                 *right_Son_Page = &free_Pos; /* O filho a direita recebe a posição livre. */
  513.                 number_of_Pages ++; /* Aumenta o número de páginas. */
  514.                 pino(p); /* Chamando função auxiliar. */
  515.                 save_Page(p, free_Pos, &new_Page); /* Salva a nova página na posição livre. */
  516.                 pino(p); /* Chamando função auxiliar. */
  517.                 save_Page(p, RRN_Atual_Page, &atual_Page); /* Salva a página atual atualizada. */
  518.                 pino(p); /* Chamando função auxiliar. */
  519.                 return 2; /* Retorna promoção. */
  520.             }
  521.         }
  522.     }
  523.     else { /* Se chegar a uma página que não existe. */
  524.         *promoter = &key_to_Insert; /* Promovido recebe a chave que está sendo inserida. */
  525.         return 2; /* Retorna promoção. */
  526.     }
  527.     return 1; /* Retorna não promoção. */
  528. }
  529.  
  530. void insert_Plane_Driver(char data[]) {
  531.     FILE *p;
  532.     p = fopen("index.dat", "rb+"); /* Abre o arquivo para leitura e escrita. */
  533.     if(p == NULL) { /* Se o arquivo não existe. */
  534.         p = fopen("index.dat", "wb+"); /* Tenta criar um arquivo para escrita e leitura. */
  535.         if(p != NULL) { /* Se foi possível criar o arquivo. */
  536.             long root = sizeof(long); /* Define o lugar onde a raiz vai ficar. */
  537.             fwrite(&root, sizeof(long), 1, p); /* Inicia a raiz na primeira posição. */
  538.             struct Page page; /* Cria a estrutura da página que será inserida. */
  539.             createNewPage(&page); /* Inicializa a página. */
  540.             fwrite(&page, sizeof(struct Page), 1, p); /* Inseri uma página vazia no arquivo que será a raiz. */
  541.             number_of_Pages = 1; /* Número de páginas na árvore = 1. */
  542.             number_of_Planes = 0; /* Como a árvore acabou de ser criada não existe voos. */
  543.         }
  544.         else {
  545.             printf("ERRO\n"); /* Feedback. */
  546.         }
  547.     }
  548.     long root;
  549.     root = load_RNN_Root(p); /* Carrega o valor da raiz para a variável root. */
  550.     struct Index key_to_Insert; /* Criando o índice que vai ser inserido. */
  551.     key_to_Insert.RRN_Plane = number_of_Planes + 1; /* O endereço no arquivo de dados será o número de voos existentes mais . */
  552.  
  553.     /* Capturando o código da string recebida. */
  554.     char codigo[15];
  555.     int i = 0;
  556.     while (i < 15) {
  557.         codigo[i] = data[i];
  558.         i++;
  559.     }
  560.     strcpy(key_to_Insert.key_Plane, codigo);
  561.                      
  562.     struct Index *promoter; /* Criando o indice promoter que será mandado por referência. */
  563.     long *right_Son_Page; /* Criando o filho a direita que será mandado por referência. */
  564.    
  565.     promoter = NULL; /* Inicializando o promoter. */
  566.     long aux = -1; /* Criando auxiliar para inicializar o filho a direita. */
  567.     right_Son_Page = &aux; /* Inicializando o filho. */
  568.     int value_return = insert_Plane(p, root, key_to_Insert, data, &promoter, &right_Son_Page); /* Chama o metodo inserir na raiz. */
  569.     if(value_return == 2) { /* Caso houve promoção. */
  570.         struct Page newbie_Page; /* Criando uma nova página pro promovido. */
  571.         struct Page gatona_Lindsay; /* Página auxiliar. */
  572.         struct Page crazy_Sierra; /* Página auxiliar. */
  573.         createNewPage(&newbie_Page); /* Inicializando a nova página. */
  574.         createNewPage(&gatona_Lindsay); /* Inicializando página auxiliar. */
  575.         createNewPage(&crazy_Sierra); /* Inicializando página auxiliar. */
  576.         newbie_Page.num_Plane = 1; /* Número de voos na nova página recebe um. */
  577.         newbie_Page.planes[0] = *promoter; /* O voo da nova página recebe o promoter. */
  578.         newbie_Page.RRN_Son[0] = root; /* O filho a esquerda do promovido recebe a antiga raiz. */
  579.         long tyler = *right_Son_Page; /* Criando auxiliar para salvar o filho a direita. */
  580.         newbie_Page.RRN_Son[1] = tyler; /* Filho a direita do promovido recebe o filho a direta do promovido. */
  581.    
  582.         long free_Pos = sizeof(long) + (number_of_Pages * sizeof(struct Page)); /* Posição vaga para inserir nova página */
  583.         number_of_Pages ++; /* Acrescimo do número de páginas. */
  584.         update_Root(free_Pos); /* Atualizando a raiz. */
  585.         load_Page(p, tyler, &gatona_Lindsay); /* Carrega a página auxiliar. */
  586.         load_Page(p, root, &crazy_Sierra); /* Carrega a página auxiliar. */
  587.         save_Page(p, free_Pos, &newbie_Page); /* Salva a nova página. */
  588.         save_Page(p, tyler, &gatona_Lindsay); /* Salva a página auxiliar. */
  589.         save_Page(p, root, &crazy_Sierra); /* Salva a página auxiliar. */
  590.         printf ("SUCESSO\n"); /* Feedback. */
  591.         number_of_Planes ++; /* Número de voos aumenta. */
  592.         save_Plane(data); /* Chama a função que salva os dados do voo. */
  593.     }
  594.     else if (value_return == 1) { /* Caso não houver promoção. */
  595.         printf ("SUCESSO\n");  /* Feedback. */
  596.         save_Plane(data); /* Chama a função que salva os dados do voo. */
  597.         number_of_Planes ++; /* Número de voos aumenta. */
  598.     }
  599.     fclose(p); /* Fecha o arquivo que foi aberto para escrita e leitura do indice. */
  600. }
  601.  
  602. void pino(FILE *p) {
  603.     struct Page page;
  604.     load_Page(p, 0, &page);
  605. }
  606.  
  607. void print_Index_Tree(FILE *p, long RRN) {
  608.  
  609.     if(RRN > 0) { /* Se a página existir. */
  610.         struct Page page; /* Declaração de uma página. */
  611.         load_Page(p, RRN, &page); /* Carregando a página do disco para a memória. */
  612.         printf("%ld|%d", RRN, page.num_Plane); /* Imprime o RRN da página e a quantidade de voos na mesma. */
  613.         int i; /* Declaração de um indice. */
  614.         for(i = 0; i < MAX_INDEX; i++) {
  615.             printf("|%ld|%s,%ld", page.RRN_Son[i], page.planes[i].key_Plane, page.planes[i].RRN_Plane); /* Imprime os RRN das páginas filhas, as chaves e o RRN das chaves no arquivo de dados. */
  616.         }
  617.         printf("|%ld|\n", page.RRN_Son[i]); /* Imprime o RRN de umas das páginas filhas. */
  618.         for(i = 0; i < MAX_INDEX + 1; i++) {
  619.             print_Index_Tree(p, page.RRN_Son[i]); /* Chama a função recursivamente em todos os filhos. */
  620.         }
  621.     }
  622.    
  623. }
  624.  
  625. void print_Plane(long RRN) {
  626.     struct Plane plane; /* Declaração de um voo. */
  627.     FILE *l; /* Declaração do ponteiro de arquivo. */
  628.     l = fopen("data.dat", "rb"); /* Abre o arquivo de dados. */
  629.     if(l != NULL) { /* Se a tentativa de abrir o arquivo for sucedida. */
  630.         fseek(l, RRN * sizeof(struct Plane), SEEK_SET); /* Move o cursor para o início dos dados da página. */
  631.         fread(&plane, sizeof(struct Plane), 1, l); /* Carrega a página do disco para a estrutura da memoria. */
  632.         printf("%s %s %s %s %s\n", plane.code_Plane, plane.arrival_Airport, plane.dest_Airport, plane.plane_Time, plane.enterprise); /* Imprime os dados do voo. */
  633.         fclose(l); /* Fecha o arquivo. */
  634.     }
  635.     else {
  636.         printf("ERRO\n"); /* Feedback. */
  637.     }
  638. }
  639.    
  640.  
  641. int search_Plane(FILE *p, long RRN_Atual_Page, char key_Plane[]) {
  642.     if(RRN_Atual_Page > 0) { /* Se a página existe. */
  643.         struct Page page; /* Declaração de uma nova página. */
  644.         load_Page(p, RRN_Atual_Page, &page); /* Carregando a página do disco para a memória. */
  645.         int i = 0; /* Declaração do indice. */
  646.         int pos = page.num_Plane; /* Inicializando a variavel pos com a quantidade de voos que tem na página. */
  647.         while(i < page.num_Plane) { /* Enquanto o indice for menor que a quantidade de voos na página. */
  648.             if(strcmp(key_Plane, page.planes[i].key_Plane) == 0) { /* Se a chave a ser inserida é igual
  649.                                                                                           a chave na posição i da página.   */
  650.                 print_Plane(page.planes[i].RRN_Plane); /* Chama a função imprimir que irá imprimir os dados do voo. */
  651.                 return 1; /* Retorna sucesso. */
  652.             }
  653.             if(strcmp(key_Plane, page.planes[i].key_Plane) < 0) { /* Se a chave a ser inserida é menor
  654.                                                                                          do que a chave na posição i da página.
  655.                                                                                          Ou seja, a chave deveria estar lá.    */
  656.                 pos = i; /* A posição que deveria estar recebe o indice atual. */
  657.                 i += MAX_INDEX + 2; /* Terminando o while para pegar a posição exata. */
  658.             }
  659.             i++; /* Acresimo do indice. */
  660.         }
  661.         search_Plane(p, page.RRN_Son[pos], key_Plane); /* Chama a função buscar recursivamente na página do filho de onde a chave deveria estar. */
  662.     }
  663.     return 0; /* Retorna erro. */
  664. }
  665.  
  666. int remove_Plane(FILE *p, long RRN_Atual_Page, char key_Plane[], int changing, struct Index *changer_Plane, int *underflow) {
  667.     struct Page atual_Page;
  668.     if(RRN_Atual_Page > -1) { /* Se o RRN da página existe. */
  669.         load_Page(p, RRN_Atual_Page, &atual_Page); /* Carregar a página do disco para a estrutura atual_Page. */
  670.         int pos = atual_Page.num_Plane; /* Inicializa pos com a quantidade de voos na página. */
  671.         int i = 0; /* Variável índice. */
  672.        
  673.         while( i < atual_Page.num_Plane) { /* Enquanto o indice for menor que a quantidade de voos. */
  674.             if(strcmp(key_Plane, atual_Page.planes[i].key_Plane) == 0) { /* Se a chave a ser inserida é igual
  675.                                                                             a chave na posição i da página.   */
  676.                 if(atual_Page.num_Plane > ORDER) { /* Se a página tem mais voos do que a ordem. Não causando underflow.*/
  677.                     if(atual_Page.RRN_Son[i+1] < 0) { /* Se o voo que será removido não tem filhos a direita. */
  678.                         atual_Page.num_Plane --; /* Menos um voo na página, pois esse poderá ser removido. */
  679.                         if(i == atual_Page.num_Plane) {
  680.                             /* Depois trocar para apenas um if. */
  681.                         }
  682.                         else {
  683.                             while(i < atual_Page.num_Plane) { /* Enquanto o indice for menor que o número de voos. */
  684.                                 atual_Page.planes[i] = atual_Page.planes[i+1]; /* Arrasta o voo uma posição para trás. */
  685.                                 atual_Page.RRN_Son[i] = atual_Page.RRN_Son[i+1]; /* Arrasta o RRN do filho uma posição para trás. */
  686.                                 i++; /* Incremento do indice. */
  687.                             }
  688.                         }
  689.                         if(changing == 1) { /* Se estiver no modo troca. */
  690.                             changer_Plane = &atual_Page.planes[i]; /* O voo auxiliar para troca recebe o que será removido. */
  691.                         }
  692.                         strcpy(atual_Page.planes[i].key_Plane, "###"); /* Preenche a chave do voo removido com ###. */
  693.                         /*pino(p);*/
  694.                         save_Page(p, RRN_Atual_Page, &atual_Page); /* Salva a página atualizada. */
  695.                         /*pino(p);*/
  696.                         return 1;              
  697.                     }
  698.                     else { /* Se o voo tem filhos a direita. */
  699.                        
  700.                     }
  701.                 }
  702.             }
  703.            
  704.             if(strcmp(key_Plane, atual_Page.planes[i].key_Plane) < 0) { /* Se a chave a ser inserida é menor
  705.                                                                            do que a chave na posição i da página.
  706.                                                                            Ou seja, a chave deveria estar lá.    */
  707.                 pos = i; /* Pos receberá a posição que a chave deveria estar. */
  708.                 i = MAX_INDEX; /* Terminando o while para pegar a posição exata. */
  709.             }
  710.             i++; /* Acrescimo do indice. */
  711.         }
  712.         remove_Plane(p, atual_Page.RRN_Son[pos], key_Plane, 0, changer_Plane, underflow); /* Chama a função remover recursivamente na página do filho de onde a chave deveria estar. */
  713.     }
  714.     else {
  715.         return 0;
  716.     }
  717.     return 1;
  718. }
  719.  
  720.  
  721. void remove_Plane_Driver(char key_Plane[]) {
  722.     FILE *p; /* Criação de ponteiro tipo arquivo. */
  723.     p = fopen("index.dat", "rb+"); /* Abrindo o arquivo de indices para leitura e escrita. */
  724.    
  725.     if(p != NULL) { /* Se o arquivo existe. */
  726.         long root;
  727.         int value_Return;
  728.        
  729.         root = load_RNN_Root(p); /* Carrega a raiz na variável root. */
  730.         struct Index *changer_Plane = NULL; /* Estruturas auxiliar que irá guardar a chave que será substuida caso necessário. */
  731.         value_Return = remove_Plane(p, root, key_Plane, 0, changer_Plane, 0); /* Chama a função remover na raiz para remover a chave. */
  732.         if(value_Return > 0) {
  733.             printf("SUCESSO\n"); /* Feedback. */
  734.         }
  735.         else {
  736.             printf("ERRO\n"); /* Feedback. */
  737.         }
  738.     }
  739.     else {
  740.         printf("ERRO\n"); /* Feedback. */
  741.     }
  742.     fclose(p);
  743. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement