/* Extendible_hashing.c -- the file that can be expanded into columns */<br/> # include <stdio. h> <br/> # include <stdlib. h> <br/> # include "extendible_hashing.h" </P> <p>/* local function declaration */</P> <p> static char pow_base_two (const int power); </P> <p>/* interface function definition */</P> <p> int Hash (const item * const pitem, const char constant) <br/>{< br/> return * pitem> constant; <br/>}</P> <p> int initializetable (table * const ptable) <br/>{< br/> * ptable = (struct tabl E *) malloc (sizeof (struct table); <br/> If (null = * ptable) <br/>{< br/> puts ("out of space. [1] "); <br/> return 0; <br/>}< br/> (* ptable)-> directory_size = m; <br/> (* ptable) -> index_digit = m/2; <br/> (* ptable)-> item_digit = lenth; <br/> (* ptable)-> array_size = m; <br/> (* ptable)-> directory = (subdirectories *) malloc (sizeof (subdirectories) * m); <br/> If (null = (* ptable) -> Di Rectory) <br/>{< br/> puts ("out of space. [2] "); <br/> free (* ptable); <br/> return 0; <br/>}< br/> (* ptable) -> directory [0]. byte_index = 0; <br/> (* ptable)-> directory [0]. point = NULL; <br/> (* ptable)-> directory [0]. point_to_itself = no; <br/> (* ptable)-> directory [1]. byte_index = 1; <br/> (* ptable)-> directory [1]. point = NULL; <br/> (* ptable)-> directory [1]. point_to_itself = no; <br/> (* PTA BLE)-> directory [2]. byte_index = 2; <br/> (* ptable)-> directory [2]. point = NULL; <br/> (* ptable)-> directory [2]. point_to_itself = no; <br/> (* ptable)-> directory [3]. byte_index = 3; <br/> (* ptable)-> directory [3]. point = NULL; <br/> (* ptable)-> directory [3]. point_to_itself = no; </P> <p> return 1; <br/>}</P> <p> int insert (const table * const ptable, const item * const pitem) <br/>{< br/> subdir Ectories * s_temp; <br/> item * arr_temp; <br/> char * d_temp; <br/> char key, constant, difference, index, and step; <br/> int ct_out, ct_lin, same_preamle, d_s_record, I _temp; </P> <p> constant = (* ptable)-> item_digit-(* ptable)-> index_digit; <br/> // obtain the first n digits <br/> key = hash (pitem, constant ); <br/>/* If the index space is empty (in the initial stage of the add operation) or, if (null = (* ptable)-> directory [Key] is not added to the created space of its own data space */<br/>. poin T | NO = (* ptable)-> directory [Key]. point_to_itself) <br/>{< br/> (* ptable)-> directory [Key]. point = (Unit *) malloc (sizeof (unit); <br/> If (null = (* ptable)-> directory [Key]. point) <br/> {<br/> puts ("out of space. [3] "); <br/> return 0; <br/>}< br/> (* ptable)-> directory [Key]. point-> array = (item *) malloc (sizeof (item) * (* ptable)-> array_size); <br/> If (null = (* ptable) -> Directo Ry [Key]. point-> array) <br/>{< br/> puts ("out of space. [4] "); <br/> free (* ptable)-> directory [Key]. point); <br/> return 0; <br/>}< br/> (* ptable)-> directory [Key]. point-> sub = 0; <br/> (* ptable)-> directory [Key]. point-> array [0] = * pitem; <br/> (* ptable)-> directory [Key]. point-> sub ++; <br/> (* ptable)-> directory [Key]. point_to_itself = yes; <br/>}< br/> // otherwise, if the index space is full (the implicit condition is to point to its own space) */< Br/> else if (* ptable)-> array_size = (* ptable)-> directory [Key]. point-> sub) <br/>{< br/> // duplicate data detection. do not add duplicate data <br/> for (ct_out = 0; ct_out <(* ptable)-> array_size; ct_out ++) <br/> If (* pitem = (* ptable)-> directory [Key]. point-> array [ct_out]) <br/> return 0; <br/> // record the index value in the directory */<br/> d_temp = (char *) malloc (sizeof (char) * (* ptable)-> directory_size); <br/> If (null = d_temp) <br/>{< br/> P UTS ("out of space. [5] "); <br/> free (* ptable)-> directory [Key]. point); <br/> free (* ptable)-> directory [Key]. point-> array); <br/> return 0; <br/>}< br/> // use the loop to expand */<br/> for (ct_out = 0, I _temp = (* ptable)-> directory_size; ct_out <I _temp; ct_out + = 4) <br/>{< br/> d_temp [ct_out + 0] = (* ptable) -> directory [ct_out + 0]. byte_index; <br/> d_temp [ct_out + 1] = (* ptable)-> directory [ct_out + 1]. byte_index; <br/> d_temp [ct_out + 2] = (* ptable)-> directory [ct_out + 2]. byte_index; <br/> d_temp [ct_out + 3] = (* ptable)-> directory [ct_out + 3]. byte_index; <br/>}< br/> // check the number of identical leading bits */<br/> arr_temp = (item *) malloc (sizeof (item) * (* ptable)-> array_size); <br/> If (null = arr_temp) <br/>{< br/> puts ("out of space. [6] "); <br/> free (* ptable)-> directory [Key]. point); <br/> free (* ptabl E)-> directory [Key]. point-> array); <br/> free (d_temp); <br/> return 0; <br/>}< br/> // record data in the data space */<br/> for (ct_out = 0, I _temp = (* ptable)-> array_size; ct_out <I _temp; ct_out ++) <br/> arr_temp [ct_out] = (* ptable)-> directory [Key]. point-> array [ct_out]; <br/>/* get the same leading digit DL */<br/> for (same_preamle = (* ptable)-> index_digit; same_preamle <= lenth; same_preamle ++) <br/> {<br/> If (arr_temp [0] >>( Lenth-same_preamle) ^ arr_temp [1] >>> (lenth-same_preamle ))! = 0) <br/>{< br/> same_preamle --; <br/> break; <br/>}< br/> If (arr_temp [0]> (lenth-same_preamle) ^ arr_temp [2]> (lenth-same_preamle ))! = 0) <br/>{< br/> same_preamle --; <br/> break; <br/>}< br/> If (arr_temp [0]> (lenth-same_preamle) ^ arr_temp [3]> (lenth-same_preamle ))! = 0) <br/>{< br/> same_preamle --; <br/> break; <br/>}< br/> // difference between the same leading bits and the original index bits */<br/> difference = same_preamle-(* ptable) -> index_digit; <br/> // update the number of Directory Index digits (at least one directory must be added when the data space is full) */<br/> (* ptable)-> index_digit = same_preamle + 1; <br/> // If DL> D */<br/> If (difference> 0) <br/> difference + = 1; <br/> else <br/> difference = 1; <br/> // create a new directory */<br/> s_temp = (* ptable)-> directory; <br/> d_s_r Ecord = (* ptable)-> directory_size; // record the original directory length <br/> (* ptable)-> directory_size = (* ptable)-> directory_size * 2 * difference; // update the directory length <br/> // update the index value */<br/> key = key * 2 * difference; <br/> (* ptable) -> directory = (subdirectories *) malloc (sizeof (subdirectories) * (* ptable)-> directory_size); <br/> If (null = (* ptable) -> directory) <br/>{< br/> puts ("out of space. [6] "); <br/> free (* ptable )-> Directory [Key]. point); <br/> free (* ptable)-> directory [Key]. point-> array); <br/> free (d_temp); <br/> free (arr_temp); <br/> return 0; <br/>}< br/> // update directory */<br/> for (ct_out = 0, step = pow_base_two (* ptable)-> index_digit)/4; ct_out <d_s_record; ct_out ++) <br/>{< br/> ct_lin = ct_out * step; <br/> (* ptable)-> directory [ct_lin]. byte_index = s_temp [ct_out]. byte_index * step; <br/> (* Ptable)-> directory [ct_lin]. point = s_temp [ct_out]. point; <br/> (* ptable)-> directory [ct_lin]. point_to_itself = s_temp [ct_out]. point_to_itself; <br/> ct_lin ++; <br/> while (ct_lin <ct_out * Step + step) <br/>{< br/> (* ptable) -> directory [ct_lin]. byte_index = (* ptable)-> directory [ct_lin-1]. byte_index + 1; <br/> (* ptable)-> directory [ct_lin]. point = s_temp [ct_out]. point; <br/> (* ptable)-> d Irectory [ct_lin]. point_to_itself = no; <br/> ct_lin ++; <br/>}< br/>/* complete the final processing of the data in the unit (at this time, the data unit must have (* ptable) -> array_size data) */<br/> // adjust all data in the data space <br/> for (ct_out = 0, I _temp = (* ptable)-> array_size; ct_out <I _temp; ct_out ++) <br/>{< br/> Index = (* ptable)-> directory [Key]. point-> array [ct_out]> (lenth-same_preamle-1); <br/> If (NO = (* ptable)-> directory [Index]. point_to_itself) <Br/> {<br/> (* ptable)-> directory [Index]. point = (Unit *) malloc (sizeof (unit); <br/> If (null = (* ptable)-> directory [Index]. point) <br/> {<br/> puts ("out of space. [7] "); <br/> free (* ptable)-> directory [Key]. point-> array); <br/> free (* ptable)-> directory [Key]. point); <br/> free (d_temp); <br/> free (arr_temp); <br/> free (* ptable)-> directory ); <br/> return 0; <br/>}< br/> (* ptabl E)-> directory [Index]. point-> array = (item *) malloc (sizeof (item) * (* ptable)-> array_size); <br/> If (null = (* ptable) -> directory [Index]. point-> array) <br/>{< br/> puts ("ouf of space. [8] "); <br/> free (* ptable)-> directory [Key]. point-> array); <br/> free (* ptable)-> directory [Key]. point); <br/> free (d_temp); <br/> free (arr_temp); <br/> free (* ptable)-> directory [Index]. point-> Array); <br/> free (* ptable)-> directory); <br/> return 0; <br/>}< br/> // initialize a new data space <br/> (* ptable)-> directory [Index]. point-> sub = 0; <br/> // Add data to the new data space <br/> (* ptable)-> directory [Index]. point-> array [0] = (* ptable)-> directory [Key]. point-> array [ct_out]; <br/> (* ptable)-> directory [Index]. point-> sub ++; <br/> (* ptable)-> directory [Index]. point_to_itself = yes; <br/> // perform operations on data in the original data space Process (Replace the last data with the location where the data is removed) <br/> (* ptable)-> directory [Key]. point-> array [ct_out] = (* ptable)-> directory [Key]. point-> array [(* ptable)-> directory [Key]. point-> sub-1]; <br/> (* ptable)-> directory [Key]. point-> sub --; <br/>}< br/> // Add new data to the data space <br/> constant = (* ptable) -> item_digit-(* ptable)-> index_digit; <br/> key = hash (pitem, constant); <br/> If (NO = (* ptable) -> directory [Ke Y]. point) <br/> {<br/> (* ptable)-> directory [Key]. point = (Unit *) malloc (sizeof (unit); <br/> If (null = (* ptable)-> directory [Key]. point) <br/> {<br/> puts ("out of space. [9] "); <br/> free (d_temp); <br/> free (arr_temp); <br/> return 0; <br/>}< br/> (* ptable)-> directory [Key]. point-> array = (item *) malloc (sizeof (item) * (* ptable)-> array_size); <br/> If (null = (* ptable) -> directory [Key]. point-> array) <br/>{< br/> puts ("out of space. [10] "); <br/> free (d_temp); <br/> free (arr_temp); <br/> free (* ptable) -> directory [Key]. point); <br/> return 0; <br/>}< br/> (* ptable)-> directory [Key]. point-> array [0] = * pitem; <br/> (* ptable)-> directory [Key]. point-> sub ++; <br/> (* ptable)-> directory [Key]. point_to_itself = yes; <br/>}< br/> else <br/>{< br/> (* ptable)-> directory [Ke Y]. point-> array [(* ptable)-> directory [Key]. point-> sub] = * pitem; <br/> (* ptable)-> directory [Key]. point-> sub ++; <br/>}< br/> free (s_temp); <br/> free (arr_temp); <br/> free (d_temp ); <br/>}< br/> // The most expected situation */<br/> else <br/> {<br/> // duplicate data detection. do not add duplicate data <br/> for (ct_out = 0; ct_out <(* ptable)-> array_size; ct_out ++) <br/> If (* pitem = (* ptable)-> directory [Key]. point-> array [ct_out]) <br/> re Turn 0; <br/> (* ptable)-> directory [Key]. point-> array [(* ptable)-> directory [Key]. point-> sub] = * pitem; <br/> (* ptable)-> directory [Key]. point-> sub ++; <br/>}</P> <p> return 1; <br/>}</P> <p> void traversal (const table * const ptable, void (* pfun) (const subdirectories )) <br/>{< br/> int count, I _temp; </P> <p> for (COUNT = 0, I _temp = (* ptable)-> directory_size; count <I _temp; Count ++) <br/>{< br/> If (Yes = (* ptable)-> directory [count]. point_to_itself) <br/> (* pfun) (* ptable)-> directory [count]); <br/>}</P> <p> int find (const table * const ptable, const item * const pitem) <br/>{< br/> item * array; <br/> int count, I _temp; <br/> char key, constant; </P> <p> constant = (* ptable)-> item_digit-(* ptable)-> index_digit; <br/> key = hash (pitem, constant ); <br/> If (null = (* ptable)-> directory [Key]. point) <br/> return 0; <br/> array = (* ptable)-> directory [Key]. point-> array; <br/> for (COUNT = 0, I _temp = (* ptable)-> array_size; count <I _temp; count ++) <br/>{< br/> If (* pitem = (* ptable)-> directory [Key]. point-> array [count]) <br/> return 1; <br/>}</P> <p> return 0; <br/>}</P> <p> int Delete (const table * const ptable, const item * const pitem) <br />{< Br/> int count, I _temp; <br/> char key, constant; </P> <p> constant = (* ptable) -> item_digit-(* ptable)-> index_digit; <br/> key = hash (pitem, constant); <br/> If (null = (* ptable) -> directory [Key]. point) <br/> return 0; <br/> for (COUNT = 0, I _temp = (* ptable)-> array_size; count <I _temp; count ++) <br/>{< br/> If (* pitem = (* ptable)-> directory [Key]. point-> array [count]) <br/>{< br/> (* Ptable)-> directory [Key]. point-> array [count] = (* ptable)-> directory [Key]. point-> array [(* ptable)-> directory [Key]. point-> sub-1]; <br/> (* ptable)-> directory [Key]. point-> sub --; <br/> return 1; <br/>}</P> <p> return 0; <br/>}</P> <p> void release (const table * const ptable) <br/>{< br/> int count; </P> <p> for (COUNT = (* ptable)-> directory_size-1; count> = 0; count --) <br/> {<br /> If (* ptable)-> directory [count]. Point! = NULL & yes = (* ptable)-> directory [count]. point_to_itself) <br/>{< br/> free (* ptable)-> directory [count]. point-> array); <br/> free (* ptable)-> directory [count]. point); <br/>}< br/> free (* ptable)-> directory); <br/> free (* ptable ); <br/>}</P> <p>/* local function definition */</P> <p> static char pow_base_two (const int power) <br/>{< br/> char count, value; </P> <p> for (COUNT = 0, value = 1; count <power; count ++) <br/> value * = 2; </P> <p> return value; <br/>}