Hash Tables are not Suitable for: Properties of a Good Hash Folding: The key is divided
Problems requiring data ordering: Hashing does not preserve the Function into equal-sized parts,
order of data, so tasks like sorting or range queries (e.g., finding 1. Minimize collisions which are then added
values between two numbers) are not possible. Multidimensional (different keys producing together to form the hash
data: Hashing treats data as single values, ignoring relationships the same hash value). value. Example: If the key
between dimensions, making it unsuitable for tasks like proximity 2. Be fast and is 123456 and divided into
searches. It struggles to handle relationships between multiple computationally efficient. parts (123, 456), the sum
dimensions. Prefix searching (long, variable-length keys): Hashing 3. Uniformly distribute keys 123 + 456 = 579 gives the
converts keys into fixed values, losing their structure, so it can't across the hash table. hash.
support prefix matching or efficiently handle variable-length keys.
Hash Function Properties: Maps key to integer: A hash function Mid Square: The key Radix Conversion: is the
converts a key (such as a string or number) into an integer, which is squared, and the process of converting a
corresponds to an index in a hash table. The resulting integer must middle digits of the number from one base (radix)
fall within the range [0, table size - 1] to ensure the key maps to a resulting number are to another. To convert between
valid position in the table. Many-to-one mapping (collision): A hash taken as the hash bases, first convert to decimal
function can sometimes map different keys to the same index in the value. Example: If by multiplying each digit by its
table, which is called a collision. This occurs because there are more the key is 123, base raised to its position and
possible keys than table slots. Collision reduction: While it's squaring it gives summing them. For decimal to
impossible to completely avoid collisions, a well-designed hash 1232 = 15129, and another base, repeatedly divide
function can reduce their frequency by distributing keys more evenly the middle digits 512 by the target base, recording
across the table. This lowers the likelihood of collisions and improves form the hash. remainders, and reverse them
the efficiency of hash table operations. for the result.
Truncation refers to Modular Arithmetic is What is Hashing? is a Factors that influence performance:
cutting off part of a only interested in process of mapping Hash function should be distribute the keys
number, usually by what the remainder is data to a fixed-size and entries evenly throughout the table and
removing digits after a when we divide A by value using a hash should minimize the collision. Collision
certain point. For example, B. For these cases function. The hash resolution strategy open addressing (store
truncating the number there is an operator function takes input key in different position) and separate
1234 to one decimal place called the modulo data (keys) and chaining(chain several key in the same
results in 34. It's commonly operator. Divide the converts it into a hash position). Table size a too large table will
used in mathematical key with some value code, which serves as cause waste of memory, small table will
operations and and use remainder as an index in a hash increase collision and force rehashing, the
programming when precise the index. table. size should be appropriate and be a prime
values are not needed. number.
What is a Min Heap? What is Max Heap? is a Heapify Process is the process of How to Know if a Heap is
is a type of binary binary tree-based data converting a binary tree into a heap. Empty? A heap is typically
heap data structure structure where each parent In the heapify process, compare a implemented as an array or a
where the parent node has a value greater node with its children to check if it dynamic data structure. To
node is always than or equal to the values satisfies the heap property: the check if a heap is empty:
smaller than or equal of its children. This property largest value is on top for a max-heap, Array Implementation: Check if
to its child nodes. ensures that the largest or the smallest for a min-heap. If the the size of the array is zero.
Where the smallest element is always at the root node violates the property, swap it Dynamic Structure: Check if the
element is always of the heap. It’s often used with the child that does. Repeat this pointer to the root node is
stored at the root in priority queues and heap process for the affected child until NULL (or the size field of the
(the top of the tree). sort. the entire subtree follows the heap structure is zero).
rules.
Build heap is the process A heap is a binary tree that is Integral operations are essential
of arranging an unordered filled completely, except for tasks directly related to achieving a
array into a valid heap possibly the last level, which is program's primary goal, such as
structure, either a max- filled from left to right. Since it's processing data or performing
heap or min-heap. It a complete binary tree, it can be calculations. Overhead operations,
involves repeatedly efficiently stored in an array, on the other hand, support the
applying the heapify with no need for pointers. For program's execution but do not
operation to the array any element at index i, the left directly contribute to its main
elements, starting from child is at position 2i, the right functionality, such as memory
the last non-leaf node and child is at position 12i + 1, and allocation, logging, or maintaining
moving upwards. the parent is at position ⌊i/2⌋ data structures.
Conversion Method 1 Folding Add Hash - Array
int option1(char key[]){ int folding(int key){ bool addHash(HASH hash[],
int ans = 0; int digit = 0; CUSTOMER cust) {
for(int i = 0; i < strlen(key); i++){ int tkey = key; int key = cust.id % SIZE;
ans += key[i]; while(tkey != 0){ bool found = true;
} tkey /= 10; int key1 = -1;
return ans; digit++; while(!found && key != key1){
} } if(key1 == -1)
int tdigit = digit/2; key1 = key;
Conversion Method 2
int first = key / power(10, if(hash[key].status != 'o')
int option2(char key[]){
tdigit); found = true;
int ans = 0;
int second = key % power(10, key = (key+1) % SIZE;
int pow = 1;
digit - tdigit); }
for(int i = 0; i < strlen(key); i++){
return first + second; hash[index] = cust;
ans += key[i] * pow;
} hash[index].status = 'o';
pow *= 27;
} Mid Square
} int midSquare(int key){ return found;
int tkey = key * key; }
Conversion Method 3
int digit = 0; Delete Hash - Array
int option3(char key[]){
int ans = 0; bool deleteHash(HASH hash[],
while(tkey != 0){ int skey){
int pow = 1;
tkey /= 10; int key = cust.id % SIZE;
int prime = 7;
digit++; bool found = false;
int len = strlen(key);
} int key1 = -1;
for(int i = 0; i < len; i++){
tkey = key * key; while(!found && key != key1){
ans += key[len - 1 - i] * pow;
digit /= 2; if(key1 == -1)
pow *= prime;
int res; key1 = key;
}
res = tkey / power(10, digit - 1); if(hash[key].status == 'o' &&
res = res % power(10, 3); hash[key].id == skey)
return ans;
} found = true;
return res; else if(hash[key].status ==
Truncation } 'e')
int truncation(int key, int n){
Linear Probing break;
return key % power(10, n);
int linear_probe(int index) { key = (key+1) % SIZE;
}
int index; }
OR
index = (index + 1) % S; hash[key].status = 'd';
void truncate(int index, int key,
return index;
int x) {
} return found;
int d;
}
d = (int)power(10, x); Double Hashing
*index = key % d; int double_hashing(int index, int Search - Array
return; key){ bool searchHash(HASH hash[],
} int INCR = 7; // must be les int skey, CUSTOMER *data){
than size int key = cust.id % SIZE;
Arithmetic
int increment = 1 + key % INCR; bool found = false;
int arith_mod(int key) {
return (index + increment) % int key1 = -1;
int index;
SIZE; while(!found && key != key1){
index = key % S;
} if(key1 == -1)
return index;
} Initialize - Array key1 = key;
void init_Hash (BKINFO bk[], if(hash[key].status == 'o' &&
Radix
BRINFO br[], TNINFO tn[]) { hash[key].id == skey)
int radix(int key, int radix){
for (int i = 0; i < 10; i++) { found = true;
int rad = 0;
bk[i].status = 'e'; else if(hash[key].status ==
int tkey = key;
br[i].status = 'e'; 'e')
int n = 0;
tn[i].status = 'e'; break;
while(tkey != 0){
} key = (key+1) % SIZE;
rad +=
} }
(tkey%radix)*power(10, n);
*data = hash[key];
n++;
hash[key].status = 'd';
tkey /= radix;
}
}
return rad;
}
Initialize Hash - LL Delete - LL Heapify
void Hash_Initialize(HASH bool Hash_Delete(HASH hash[], void heapify(int index, int arr[],
hash[]){ int key){ int hsize){
for(int i = 0; i < TableSize; i++){ int index; int left = index*2;
hash[i] = NULL; bool found = false; int right = index*2 + 1;
} index = key % TableSize; int smallest;
} nd tp = hash[index].head, tp1;
while(tp != NULL && !found){ if(left < hsize && arr[left] <
Add Hash - LL if(tp->cust.id == key){ arr[index])
void Hash_Add(HASH hash[], if(tp1 == NULL) smallest = left;
CUSTOMER cust){ hash[index].head = else
int index; NULL; smallest = index;
index = cust.id % TableSize; else if(tp->next == NULL) if(right < hsize && arr[right] <
nd tp = malloc(sizeof(NODE)); tp1->next = NULL; arr[smallest])
tp->cust = cust; else smallest = right;
tp->next = NULL: tp1->next = tp->next; if(smallest != index){
else int temp = arr[smallest];
if(hash[index].head != NULL) found = true; arr[smallest] = arr[index];
tp->next = hash[index].head; free(tp); arr[index] = arr[temp];
hash[index].head = tp; }
} else{ heapify(smallest, arr, hsize);
Add Hash - LL tp1 = tp; }
void Hash_AddBook(HASHBK tp = tp->next; }
hashbk[], BKINFO book) { }
int key = }
option2Convert(book.bkNumber return found;
); }
int radixConvertedKey = Heap Insert
radix(key, 11); void insert(Heap *heap, int val){
int index = radixConvertedKey % int j = ++heap->hsize;
TableSize; while(heap->arr[j/2] > val){
heap->arr[j] = heap->arr[j/2];
ndBook tp = j /= 2;
malloc(sizeof(NODEBOOK)); }
tp->book = book; heap->arr[j] = val;
tp->next = NULL; }
if (hashbk[index].head != NULL) { Delete heap
tp->next = hashbk[index].head; void delete(Heap *heap){
} int val = heap->arr[heap-
hashbk[index].head = tp; >hsize--];
} heapify(1, heap->arr, hsize);
return val;
Search - LL }
bool Hash_Search(HASH hash[],
int key, CUSTOMER *data){ Heap Full
int index; bool isFull(int hsize){
bool found = false; bool full = false;
index = cust.id % TableSize; if(hsize == SIZE-1)
nd tp = hash[index].head, tp1; full = true;
while(tp != NULL && !found){ return full;
if(tp->cust.id == key){ }
*data = tp->cust; Heap Empty
} bool isEmpty(int hsize){
else{ bool empty = false;
tp1 = tp; if(hsize == 0)
tp = tp->next; empty = true;
} return empty;
} }
return found;
}