Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Chapter 3
Data Structures
Yonas Y.
Algorithm Analysis and Design
School of Electrical and Computer Engineering
1
Outline Elementary Data Structures Hash Tables Binary Search Trees
2 Hash Tables
Direct-address tables
Hash tables
Hash functions
2
Outline Elementary Data Structures Hash Tables Binary Search Trees
Figure : 3.1 An array implementation of a stack S. Stack elements appear only in the
lightly shaded positions.
3
Outline Elementary Data Structures Hash Tables Binary Search Trees
PUSH(S,x)
1 S.top = S.top + 1
2 S[S.top] = x
POP(S)
1 if STACK-EMPTY(S)
2 error ”underflow”
3 else S.top = S.top − 1
4 return S[S.top + 1]
Each of the three stack operations takes O(1) time.
4
Outline Elementary Data Structures Hash Tables Binary Search Trees
Figure : 3.2 A queue implemented using an array Q[1..12]. Queue elements appear
only in the lightly shaded positions. 5
Outline Elementary Data Structures Hash Tables Binary Search Trees
DEQUEUE(Q)
1 x = Q[Q.head]
2 if Q.head == Q.length
3 Q.head = 1
4 else Q.head = Q.head + 1
5 return x
Each operation takes O(1) time.
6
Outline Elementary Data Structures Hash Tables Binary Search Trees
Linked lists
Linked lists
A linked list is a data structure in which the objects are arranged in a linear
order.
Unlike an array, however, in which the linear order is determined by the
array indices, the order in a linked list is determined by a pointer in each
object.
As shown in Figure 3.3, each element of a doubly linked list L is an object
with an attribute key and two other pointer attributes: next and prev.
Given an element x in the list, x.next points to its successor in the linked
list, and x.prev points to its predecessor.
If x.prev = NIL, the element x has no predecessor and is therefore the first
element, or head, of the list.
If x.next = NIL, the element x has no successor and is therefore the last
element, or tail, of the list.
Linked lists
LIST-SEARCH(L, k)
1 x = L.head
2 while x 6= NIL and x.key 6= k
3 x = x.next
4 return x
The LIST-SEARCH procedure takes Θ(n) time in the worst case.
8
Outline Elementary Data Structures Hash Tables Binary Search Trees
Linked lists
9
Outline Elementary Data Structures Hash Tables Binary Search Trees
Linked lists
LIST-DELETE(L, x)
1 if x.prev 6= NIL
2 x.prev .next = x.next
3 else L.head = x.next
4 if x.next 6= NIL
5 x.next.prev = x.prev
LIST-DELETE runs in O(1) time.
If we wish to delete an element with a given key, Θ(n) time is required in
the worst case because we must first call LIST-SEARCH to find the
element.
10
Outline Elementary Data Structures Hash Tables Binary Search Trees
Direct-address tables
Hash Tables:
Direct-address tables
Direct addressing is a simple technique that works well when the universe U of
keys is reasonably small.
Maintain a dynamic set.
Each element has a key drawn from a universe U = {0, 1, ..., m − 1}.
No two elements have the same key.
To represent the dynamic set, use a direct-address table, or array,
T [0...m − 1]:
Each slot, or position, corresponds to a key in U.
If there’s an element x with key k, then T [k] contains a pointer to x.
Otherwise, T [k] is empty, represented by NIL.
Hash tables
Hash tables
Idea: Instead of storing an element with key k in slot k, use a function h and
store the element in slot h(k).
We call h a hash function.
h : U → 0, 1, ..., m − 1, so that h(k) is a legal slot number in T .
We say that k hashes to slot h(k).
Hash tables
Hash tables
Search:
CHAINED-HASH-SEARCH(T, k)
1 search for an element with key k in list T [h(k)]
Running time is proportional to the length of the list of elements in slot
h(k).
Deletion:
CHAINED-HASH-DELETE(T, x)
1 delete x from the list T [h(key [x])]
Given pointer x to the element to delete, so no search is needed to find
this element.
Worst-case running time is O(1) time if the lists are doubly linked.
If the lists are singly linked, then deletion takes as long as searching,
because we must find x 0 s predecessor in its list in order to correctly update
next pointers.
15
Outline Elementary Data Structures Hash Tables Binary Search Trees
Hash tables
Hash functions
Hash functions
17
Outline Elementary Data Structures Hash Tables Binary Search Trees
Hash functions
Division method
In the division method for creating hash functions, we map a key k into one of
m slots by taking the remainder of k divided by m.
h(k) = k mod m.
Example: m = 20 and k = 91 ⇒ h(k) = 11.
Advantage: Fast, since requires just one division operation.
Disadvantage: Have to avoid certain values of m:
Powers of 2 are bad. If m = 2p for integer p, then h(k) is just the least
significant p bits of k.
If k is a character string interpreted in radix 2p (as in CLRS example),
then m = 2p − 1 is bad.
Good choice for m: A prime not too close to an exact power of 2.
Multiplication method
The multiplication method for creating hash functions operates in the ff steps.
1 Choose constant A in the range 0 < A < 1.
2 Multiply key k by A.
Put another way, h(k) = bm(kA mod 1)c, where kA mod 1 = kA - bkAc =
fractional part of kA. 18
Outline Elementary Data Structures Hash Tables Binary Search Trees
Hash functions
Figure : 3.8 Binary search trees. For any node x, the keys in the left subtree of x are
20
at most x.key , and the keys in the right subtree of x are at least x.key .
Outline Elementary Data Structures Hash Tables Binary Search Trees
INORDER-TREE-WALK(x)
1 6 NIL
if x =
2 INORDER-TREE-WALK(x.left)
3 print x.key
4 INORDER-TREE-WALK(x.right)
Example: Do the inorder tree walk on figure 3.8, getting the output ABDFHK.
Correctness: Follows by induction directly from the binary-search-tree property.
Time: Intuitively, the walk takes Θ(n) time for a tree with n nodes, because we
visit and print each node once.
21
Outline Elementary Data Structures Hash Tables Binary Search Trees
TREE-MINIMUM(x)
1 while x.left 6= NIL
2 x = x.left
3 return x
The pseudocode for TREE-MAXIMUM is symmetric.
Time: Both procedures visit nodes that form a downward path from the root
to a leaf. Both procedures run in O(h) time, where h is the height of the tree.
TREE-SUCCESSOR(x)
1 if x.right 6= NIL
2 return TREE-MINIMUM(x.right)
3 y = x.p
4 while y 6= NIL and x == y .right
5 x =y
6 y = y .p
7 return y
TREE-PREDECESSOR is symmetric to TREE-SUCCESSOR.
Time: For both the TREE-SUCCESSOR and TREE-PREDECESSOR
procedures, in both cases, we visit nodes on a path down the tree or up the
tree. Thus, running time is O(h), where h is the height of the tree.
24
Outline Elementary Data Structures Hash Tables Binary Search Trees
Example:
Find the successor of the node with key value 15. (Answer: Key value 17)
Find the successor of the node with key value 6. (Answer: Key value 7)
Find the successor of the node with key value 4. (Answer: Key value 6)
Find the predecessor of the node with key value 6. (Answer: Key value 4)
25
Outline Elementary Data Structures Hash Tables Binary Search Trees
To insert value v into the binary search tree, the procedure is given node
z, with key [z] = v , left[z] = NIL , and right[z] = NIL.
Beginning at root of the tree, trace a downward path, maintaining two
pointers.
Pointer x: traces the downward path.
Pointer y: ”trailing pointer” to keep track of parent of x.
Traverse the tree downward by comparing the value of node at x with v,
and move to the left or right child accordingly.
When x is NIL , it is at the correct position for node z.
Compare z’s value with y’s value, and insert z at either y’s left or right,
appropriately.
Figure : 3.10 Inserting an item with key 13 into a binary search tree.
Deletion
TREE-DELETE is broken into three cases.
Case 1: z has no children.
Delete z by making the parent of z point to NIL, instead of to z.
Case 2: z has one child.
Delete z by making the parent of z point to zs child, instead of to z.
Case 3: z has two children.
z’s successor y has either no children or one child. (y is the minimum
node-with no left child-in z’s right subtree.)
Delete y from the tree (via Case 1 or 2).
Replace z’s key and satellite data with y’s.
Time: O(h), on a tree of height h.
28
Outline Elementary Data Structures Hash Tables Binary Search Trees