Advertisement
Guest User

Untitled

a guest
Nov 17th, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.51 KB | None | 0 0
  1. /* c016.c: **********************************************************}
  2. {* Téma:  Tabulka s Rozptýlenými Položkami
  3. **                      První implementace: Petr Přikryl, prosinec 1994
  4. **                      Do jazyka C prepsal a upravil: Vaclav Topinka, 2005
  5. **                      Úpravy: Karel Masařík, říjen 2014
  6. **                              Radek Hranický, 2014-2018
  7. **
  8. ** Vytvořete abstraktní datový typ
  9. ** TRP (Tabulka s Rozptýlenými Položkami = Hash table)
  10. ** s explicitně řetězenými synonymy. Tabulka je implementována polem
  11. ** lineárních seznamů synonym.
  12. **
  13. ** Implementujte následující procedury a funkce.
  14. **
  15. **  HTInit ....... inicializuje tabulku před prvním použitím
  16. **  HTInsert ..... vložení prvku
  17. **  HTSearch ..... zjištění přítomnosti prvku v tabulce
  18. **  HTDelete ..... zrušení prvku
  19. **  HTRead ....... přečtení hodnoty prvku
  20. **  HTClearAll ... zrušení obsahu celé tabulky (inicializace tabulky
  21. **                 poté, co již byla použita)
  22. **
  23. ** Definici typů naleznete v souboru c016.h.
  24. **
  25. ** Tabulka je reprezentována datovou strukturou typu tHTable,
  26. ** která se skládá z ukazatelů na položky, jež obsahují složky
  27. ** klíče 'key', obsahu 'data' (pro jednoduchost typu float), a
  28. ** ukazatele na další synonymum 'ptrnext'. Při implementaci funkcí
  29. ** uvažujte maximální rozměr pole HTSIZE.
  30. **
  31. ** U všech procedur využívejte rozptylovou funkci hashCode.  Povšimněte si
  32. ** způsobu předávání parametrů a zamyslete se nad tím, zda je možné parametry
  33. ** předávat jiným způsobem (hodnotou/odkazem) a v případě, že jsou obě
  34. ** možnosti funkčně přípustné, jaké jsou výhody či nevýhody toho či onoho
  35. ** způsobu.
  36. **
  37. ** V příkladech jsou použity položky, kde klíčem je řetězec, ke kterému
  38. ** je přidán obsah - reálné číslo.
  39. */
  40.  
  41. #include "c016.h"
  42.  
  43. int HTSIZE = MAX_HTSIZE;
  44. int solved;
  45.  
  46. /*          -------
  47. ** Rozptylovací funkce - jejím úkolem je zpracovat zadaný klíč a přidělit
  48. ** mu index v rozmezí 0..HTSize-1.  V ideálním případě by mělo dojít
  49. ** k rovnoměrnému rozptýlení těchto klíčů po celé tabulce.  V rámci
  50. ** pokusů se můžete zamyslet nad kvalitou této funkce.  (Funkce nebyla
  51. ** volena s ohledem na maximální kvalitu výsledku). }
  52. */
  53.  
  54. int hashCode ( tKey key ) {
  55.     int retval = 1;
  56.     int keylen = strlen(key);
  57.     for ( int i=0; i<keylen; i++ )
  58.         retval += key[i];
  59.     return ( retval % HTSIZE );
  60. }
  61.  
  62. /*
  63. ** Inicializace tabulky s explicitně zřetězenými synonymy.  Tato procedura
  64. ** se volá pouze před prvním použitím tabulky.
  65. */
  66.  
  67. void htInit ( tHTable* ptrht ) {
  68.  
  69.     if((*ptrht) != NULL) {
  70.         for(int i = 0; i < HTSIZE; i++){
  71.             (*ptrht)[i] = NULL;
  72.         }
  73.     }
  74. }
  75.  
  76. /* TRP s explicitně zřetězenými synonymy.
  77. ** Vyhledání prvku v TRP ptrht podle zadaného klíče key.  Pokud je
  78. ** daný prvek nalezen, vrací se ukazatel na daný prvek. Pokud prvek nalezen není,
  79. ** vrací se hodnota NULL.
  80. **
  81. */
  82.  
  83. tHTItem* htSearch ( tHTable* ptrht, tKey key ) {
  84.     int Take_hash = hashCode(key);
  85.     tHTItem * Item = (*ptrht)[Take_hash];
  86.     if((*ptrht) != NULL){ ///Kontrola zda existuje nějaká tabulka
  87.         while(Item != NULL){
  88.             if(!strcmp(Item->key, key)){
  89.                 return Item;
  90.             }
  91.             Item = Item->ptrnext;
  92.         }
  93.     }
  94.     return NULL;
  95. }
  96.  
  97. /*
  98. ** TRP s explicitně zřetězenými synonymy.
  99. ** Tato procedura vkládá do tabulky ptrht položku s klíčem key a s daty
  100. ** data.  Protože jde o vyhledávací tabulku, nemůže být prvek se stejným
  101. ** klíčem uložen v tabulce více než jedenkrát.  Pokud se vkládá prvek,
  102. ** jehož klíč se již v tabulce nachází, aktualizujte jeho datovou část.
  103. **
  104. ** Využijte dříve vytvořenou funkci htSearch.  Při vkládání nového
  105. ** prvku do seznamu synonym použijte co nejefektivnější způsob,
  106. ** tedy proveďte.vložení prvku na začátek seznamu.
  107. **/
  108.  
  109. void htInsert ( tHTable* ptrht, tKey key, tData data ) {
  110.     tHTItem *Item = htSearch(ptrht, key);
  111.     if((*ptrht) != NULL){ ///kontrola zda existuje tabulka
  112.         tHTItem * Item2 = malloc(sizeof(struct tHTItem));
  113.         if(Item == NULL) {
  114.             int Take_Hash = hashCode(key); ///zjistime, kam ulozime index
  115.             Item2->key = key;
  116.             Item2->data = data;
  117.             Item2->ptrnext = (*ptrht)[Take_Hash];
  118.             (*ptrht)[Take_Hash] = Item2;
  119.         }
  120.         else{
  121.             Item->data = data;
  122.         }
  123.     }
  124. }
  125.  
  126.  
  127. /*
  128. ** TRP s explicitně zřetězenými synonymy.
  129. ** Tato funkce zjišťuje hodnotu datové části položky zadané klíčem.
  130. ** Pokud je položka nalezena, vrací funkce ukazatel na položku
  131. ** Pokud položka nalezena nebyla, vrací se funkční hodnota NULL
  132. **
  133. ** Využijte dříve vytvořenou funkci HTSearch.
  134. */
  135.  
  136. tData* htRead ( tHTable* ptrht, tKey key ) {
  137.     if(ptrht != NULL){ ///kontrola, zda existuje tabulka
  138.         tHTItem *Item = htSearch(ptrht, key);
  139.         if(Item != NULL){
  140.             return &(Item->data);
  141.         }
  142.         else{
  143.             return NULL;
  144.         }
  145.     }
  146.     else{
  147.         return NULL;
  148.     }
  149. }
  150.  
  151. /*
  152. ** TRP s explicitně zřetězenými synonymy.
  153. ** Tato procedura vyjme položku s klíčem key z tabulky
  154. ** ptrht.  Uvolněnou položku korektně zrušte.  Pokud položka s uvedeným
  155. ** klíčem neexistuje, dělejte, jako kdyby se nic nestalo (tj. nedělejte
  156. ** nic).
  157. **
  158. ** V tomto případě NEVYUŽÍVEJTE dříve vytvořenou funkci HTSearch.
  159. */
  160.  
  161. void htDelete ( tHTable* ptrht, tKey key ) {
  162.  
  163.     int Take_Hash = hashCode(key); /// ziskani klice
  164.     tHTItem * Item = (*ptrht)[Take_Hash];
  165.     tHTItem * Item2 = (*ptrht)[Take_Hash];
  166.     if(ptrht != NULL){ ///jestli nejaka tabulka existuje
  167.         while(Item->ptrnext != NULL){
  168.             if (strcmp(key, Item->key) == 0){
  169.                 if(Item == (*ptrht)[Take_Hash]){
  170.                     (*ptrht)[Take_Hash] = Item2->ptrnext;
  171.                 }
  172.                 else{
  173.                 Item->ptrnext = Item2->ptrnext;
  174.                 free(Item);
  175.                 break;
  176.                 }
  177.             }
  178.         Item = Item2;
  179.         Item2 = Item2->ptrnext;
  180.         }
  181.     }
  182. }
  183.  
  184. /* TRP s explicitně zřetězenými synonymy.
  185. ** Tato procedura zruší všechny položky tabulky, korektně uvolní prostor,
  186. ** který tyto položky zabíraly, a uvede tabulku do počátečního stavu.
  187. */
  188.  
  189. void htClearAll ( tHTable* ptrht ) {
  190.     int i = 0;
  191.     tHTItem *Item;
  192.     tHTItem *Item2;
  193.     if(ptrht != NULL){///kontrola, zda nejaka tabulka existuje
  194.         while(i < HTSIZE){ ///Projedeme vsechny indexy v tabulce
  195.             i++;
  196.             Item = ((*ptrht)[i]);
  197.             while(Item != NULL){///Projedeme vsechny polozky zretezenych seznamu
  198.                 Item2 = Item->ptrnext;
  199.                 free(Item->key);
  200.                 free(Item);
  201.                 Item = Item2; ///uvolneni polozky z pameti
  202.             }
  203.             (*ptrht)[i] = NULL;
  204.         }
  205.     }
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement