Professional Documents
Culture Documents
Kaustubh Bhattacharya PDF
Kaustubh Bhattacharya PDF
Jennifer Rexford!
Motivating Quotations!
Every program depends on algorithms and data
structures, but few programs depend on the
invention of brand new ones.!
-- Kernighan & Pike!
A Common Task!
Maintain a table of key/value pairs!
Each key is a string; each value is an int
Unknown number of key-value pairs!
Examples!
(student name, grade)!
(john smith, 84), (jane doe, 93), (bill clinton, 81)!
(baseball player, number)!
(Ruth, 3), (Gehrig, 4), (Mantle, 7)!
(variable name, value)!
(maxLength, 2000), (i, 7), (j, -10)!
Algorithms!
Create: Create the data structure!
Add: Add a key/value pair!
Search: Search for a key/value pair, by key!
Free: Free the data structure!
"Gehrig"
4
"Ruth"
3
NULL
Algorithms:!
Create: Allocate Table structure to point to first node!
Add: Insert new node at front of list!
Search: Linear search through the list!
Free: Free nodes while traversing; free Table structure!
6
struct!
Table!
struct!
Node!
struct!
Node!
"Gehrig"
4
"Ruth"
3
NULL
7
t = Table_create();
t!
t = Table_create();
t!
NULL
These are
pointers to!
strings!
struct Table
Table_add(t,
Table_add(t,
Table_add(t,
*t;
"Ruth", 3);
"Gehrig", 4);
"Mantle", 7);
t!
"Gehrig"
4
"Ruth"
3
NULL
10
Table_add(t,
Table_add(t,
Table_add(t,
p!
*t;
"Ruth", 3);
"Gehrig", 4);
"Mantle", 7);
t!
"Gehrig"
4
"Ruth"
3
NULL
11
Table_add(t,
Table_add(t,
Table_add(t,
p!
t!
"Mantle"
7
"Gehrig"
4
*t;
"Ruth", 3);
"Gehrig", 4);
"Mantle", 7);
"Ruth"
3
NULL
12
Table_add(t,
Table_add(t,
Table_add(t,
p!
t!
"Mantle"
7
"Gehrig"
4
*t;
"Ruth", 3);
"Gehrig", 4);
"Mantle", 7);
"Ruth"
3
NULL
13
Table_add(t,
Table_add(t,
Table_add(t,
p!
t!
"Mantle"
7
"Gehrig"
4
*t;
"Ruth", 3);
"Gehrig", 4);
"Mantle", 7);
"Ruth"
3
NULL
14
found =
Table_search(t, "Gehrig", &value);
t!
"Mantle"
7
"Gehrig"
4
"Ruth"
3
NULL
15
found =
Table_search(t, "Gehrig", &value);
p!
t!
"Mantle"
7
"Gehrig"
4
"Ruth"
3
NULL
16
found =
Table_search(t, "Gehrig", &value);
p!
t!
"Mantle"
7
"Gehrig"
4
"Ruth"
3
NULL
17
found =
Table_search(t, "Gehrig", &value);
p!
t!
"Mantle"
7
"Gehrig"
4
"Ruth"
3
NULL
18
found =
Table_search(t, "Gehrig", &value);
p!
t!
"Mantle"
7
"Gehrig"
4
"Ruth"
3
NULL
19
found =
Table_search(t, "Gehrig", &value);
p!
t!
"Mantle"
7
"Gehrig"
4
"Ruth"
3
NULL
20
Table_free(t);
t!
"Mantle"
7
"Gehrig"
4
"Ruth"
3
NULL
21
Table_free(t);
p!
t!
"Mantle"
7
"Gehrig"
4
"Ruth"
3
NULL
22
Table_free(t);
p!
nextp!
"Mantle"
7
"Gehrig"
4
t!
"Ruth"
3
NULL
23
Table_free(t);
p! nextp!
t!
"Mantle"
7
"Gehrig"
4
"Ruth"
3
NULL
24
Table_free(t);
p!
nextp!
"Gehrig"
4
"Ruth"
3
NULL
t!
"Mantle"
7
25
Table_free(t);
p! nextp!
t!
"Mantle"
7
"Gehrig"
4
"Ruth"
3
NULL
26
Table_free(t);
p!
nextp!
t!
"Mantle"
7
"Gehrig"
4
"Ruth"
3
NULL
27
Table_free(t);
p!
t!
"Mantle"
7
"Gehrig"
4
nextp!
"Ruth"
3
NULL
28
Table_free(t);
p!
t!
"Mantle"
7
"Gehrig"
4
nextp!
"Ruth"
3
NULL
29
!fast!
Add:!
!fast!
Search:
!slow!
Free:
!slow!
Would it be better to
keep the nodes
sorted by key?!
30
ARRAYSIZE-1
struct Node *array[ARRAYSIZE];
31
1776
Revolution
1861
Civil
1939
WW2
32
This is OK:!
0
ARRAYSIZE-1
33
ARRAYSIZE-1
35
hash(the) = 965156977.
965156977 % 7 = 1.!
Search the linked list table[1] for the string the; not found.!
0
1
2
3
4
5
6
37
hash(the) = 965156977.
965156977 % 7 = 1.!
Search the linked list table[1] for the string the; not found!
Now: table[1] = makelink(key, value, table[1])!
0
1
2
3
4
5
6
the
38
hash(cat) = 3895848756.
3895848756 % 7 = 2.!
Search the linked list table[2] for the string cat; not found!
Now: table[2] = makelink(key, value, table[2])!
0
1
2
3
4
5
6
the
39
Search the linked list table[5] for the string in; not found!
Now: table[5] = makelink(key, value, table[5])!
0
1
2
3
4
5
6
the
cat
40
hash(the) = 965156977.
965156977 % 7 = 1.!
Search the linked list table[1] for the string the; found it!!
0
1
2
3
4
5
6
the
cat
in
41
hash(hat) = 865559739.
865559739 % 7 = 2.!
Search the linked list table[2] for the string hat; not found.!
Now, insert hat into the linked list table[2]. !
At beginning or end? Doesnt matter.!
0
1
2
3
4
5
6
the
cat
in
42
0
1
2
3
4
5
6
the
hat
cat
in
43
struct!
Table!
0 NULL
1 NULL
23
723
806 NULL
1023 NULL
struct!
Node!
"Ruth"
3
NULL
struct!
Node!
"Gehrig"
4
NULL
44
t = Table_create();
t!
0 NULL
1 NULL
1023 NULL
45
p->next = t->array[h];
Table_add(t, "Ruth", 3);
t->array[h] = p;
Table_add(t, "Gehrig", 4);
}
Table_add(t, "Mantle", 7);
t!
0 NULL
1 NULL
23
723
806 NULL
1023 NULL
"Ruth"
3
NULL
These are
pointers to
strings!
"Gehrig"
4
NULL
46
p->next = t->array[h];
Table_add(t, "Ruth", 3);
t->array[h] = p;
Table_add(t, "Gehrig", 4);
}
Table_add(t, "Mantle", 7);
t!
0 NULL
1 NULL
23
723
806 NULL
1023 NULL
"Ruth"
3
NULL
"Gehrig"
4
NULL
p!
47
p->next = t->array[h];
Table_add(t, "Ruth", 3);
t->array[h] = p;
Table_add(t, "Gehrig", 4);
}
Table_add(t, "Mantle", 7);
t!
0 NULL
1 NULL
23
723
806 NULL
1023 NULL
"Ruth"
3
NULL
p!
"Mantle"
7
48
p->next = t->array[h];
Table_add(t, "Ruth", 3);
t->array[h] = p;
Table_add(t, "Gehrig", 4);
}
Table_add(t, "Mantle", 7);
t!
0 NULL
1 NULL
23
723
806 NULL
1023 NULL
"Ruth"
3
NULL
h = 806!
"Gehrig"
4
NULL
p!
"Mantle"
7
NULL
49
p->next = t->array[h];
Table_add(t, "Ruth", 3);
t->array[h] = p;
Table_add(t, "Gehrig", 4);
}
Table_add(t, "Mantle", 7);
t!
0 NULL
1 NULL
23
723
806
1023 NULL
"Ruth"
3
NULL
h = 806!
"Gehrig"
4
NULL
p!
"Mantle"
7
NULL
50
return 0;
found =
}
Table_search(t, "Gehrig", &value);
t!
0 NULL
1 NULL
23
723
806
1023 NULL
"Ruth"
3
NULL
"Gehrig"
4
NULL
"Mantle"
7
NULL
51
return 0;
found =
}
Table_search(t, "Gehrig", &value);
t!
0 NULL
1 NULL
23
723
806
1023 NULL
"Ruth"
3
NULL
"Mantle"
7
NULL
52
return 0;
found =
}
Table_search(t, "Gehrig", &value);
t!
0 NULL
1 NULL
23
723
806
1023 NULL
p!
"Ruth"
3
NULL
"Gehrig"
4
NULL
h = 723!
"Mantle"
7
NULL
53
return 0;
found =
}
Table_search(t, "Gehrig", &value);
t!
0 NULL
1 NULL
23
723
806
1023 NULL
p!
"Ruth"
3
NULL
"Gehrig"
4
NULL
h = 723!
"Mantle"
7
NULL
54
return 0;
found =
}
Table_search(t, "Gehrig", &value);
t!
0 NULL
1 NULL
23
723
806
1023 NULL
p!
"Ruth"
3
NULL
"Gehrig"
4
NULL
h = 723!
"Mantle"
7
NULL
55
Table_free(t);
t!
0 NULL
1 NULL
23
723
806
1023 NULL
"Ruth"
3
NULL
"Gehrig"
4
NULL
"Mantle"
7
NULL
56
Table_free(t);
t!
0 NULL
1 NULL
23
723
806
1023 NULL
b = 0!
"Ruth"
3
NULL
"Gehrig"
4
NULL
"Mantle"
7
NULL
57
t!
p!
0 NULL
1 NULL
23
723
806
Table_free(t);
1023 NULL
b = 0!
"Ruth"
3
NULL
"Gehrig"
4
NULL
"Mantle"
7
NULL
58
t!
p!
0 NULL
1 NULL
23
723
806
Table_free(t);
1023 NULL
b = 1, , 23!
"Ruth"
3
NULL
"Gehrig"
4
NULL
"Mantle"
7
NULL
59
t!
p!
0 NULL
1 NULL
23
723
806
Table_free(t);
1023 NULL
b = 23!
"Ruth"
3
NULL
"Gehrig"
4
NULL
"Mantle"
7
NULL
60
t!
p!
0 NULL
1 NULL
23
723
806
1023 NULL
"Ruth"
3
NULL
nextp!
"Gehrig"
4
NULL
Table_free(t);
b = 23!
"Mantle"
7
NULL
61
t!
p! nextp!
0 NULL
1 NULL
23
723
806
1023 NULL
"Ruth"
3
NULL
"Gehrig"
4
NULL
Table_free(t);
b = 23!
"Mantle"
7
NULL
62
Table_free(t);
t!
0 NULL
1 NULL
23
723
806
1023 NULL
"Ruth"
3
NULL
b = 24, , 723!
b = 724, , 806!
b = 807, , 1024!
"Gehrig"
4
NULL
"Mantle"
7
NULL
63
Table_free(t);
t!
0 NULL
1 NULL
23
723
806
1023 NULL
b = 1024!
"Ruth"
3
NULL
"Gehrig"
4
NULL
"Mantle"
7
NULL
64
!fast!
Search: !fast!
Free:
!slow!
Is hash table
search always
fast?!
65
Key Ownership!
Note: Table_add() functions contain this code:!
void Table_add(struct Table *t, const char *key, int value) {
66
Table_add(t, k, 3);
strcpy(k, "Gehrig");
67
Summary!
Common data structures & associated algorithms!
Linked list!
Fast insert, slow search!
Hash table!
Fast insert, (potentially) fast search!
Invaluable for storing key/value pairs!
Very common!
Related issues!
Hashing algorithms!
Memory ownership!
69
Appendix!
Stupid programmer tricks related to hash tables!
70
0 0 1 1 0 1 0 1
53 % 16 is 5, the last four bits of the number!
32 16 8 4 2 1
0 0 0 0 0 1 0 1
Would like an easy way to isolate the last four bits !
71
Bitwise OR (|)!
& 0 1
0 1
0 0
0 1
0 1
1 1
Turns 0 to 1, and 1 to 0!
E.g., set last three bits to 0!
x = x & ~7;!
0 0 0 0 0 1 0 1
72
Previous!
version!
Faster!
What happens if
you mistakenly
write h & 1024?!
73
much faster?!
74