Basic Data Structures CS 583 Analysis of Algorithms 7/1/2016

advertisement
Basic Data Structures
CS 583
Analysis of Algorithms
7/1/2016
CS583 Fall'06: Basic Data Structures
1
Outline
• HW1 analysis
• Basic Data Structures
–
–
–
–
Stacks
Queues
Linked lists
Rooted trees
• Binary Search Trees
– Tree walk
– Querying
7/1/2016
CS583 Fall'06: Basic Data Structures
2
HW1
• HW1 answers are posted on the web site
• Check results by e-mail to the TA, or with the
instructor in the class
– The grade can be changed within 1 week, by October 9.
• Submitting HW in the future:
– Attach the submission in a separate file, and double-check
that it’s not empty.
– Prefix the file name with the student’s last name, e.g.
JonesHw1.doc.
– Indent a pseudocode properly.
7/1/2016
CS583 Fall'06: Basic Data Structures
3
Stacks
• Stack is a dynamic data set in which the element
deleted from the set is the latest inserted: last-infirst-out, or LIFO policy.
– The insert operation on stack is often called PUSH
– The delete operation is often called POP.
• A stack can be implemented by an array S[1..n] with
an attribute top[S] that indexes the most recently
inserted element.
– When top[S] = 0, the stack is empty.
– If an empty stack is popped, we say the stack underflows.
– When top[S] > n, the stack overflows.
7/1/2016
CS583 Fall'06: Basic Data Structures
4
Stack Algorithms
Stack-Empty(S)
1 if top[S] = 0
2
return TRUE
3 else
4
return FALSE
Push(S, x)
1 top[S]++
2 S[top[S]] = x
Pop(S)
1 if Stack-Empty(S)
2
throw "underflow"
3 else
4
top[S]—
5 return S[top[S]+1]
Each of above algorithms runs in O(1) time.
7/1/2016
CS583 Fall'06: Basic Data Structures
5
Queues
• The queue implements a first-in-first-out, or FIFO
policy.
– The insert operation on a queue is called ENQUEUE
– The delete operation is called DEQUEUE.
• A queue of at most (n-1) elements can be
implemented using an array Q[1..n].
– The queue has an attribute head[Q] that points to the
index of its head.
– The attribute tail[Q] indexes the next location at which
the new element will be inserted.
– The order is circular, i.e. the location 1 immediately
follows the location n.
7/1/2016
CS583 Fall'06: Basic Data Structures
6
Queues: Example
1
13
2
3
tail
4
11
head
5
12
4
5
12
head
Q[1..5]
5
12
head
Q[1..5]
Q[1..5]
11 = Dequeue(Q):
1
13
2
3
tail
Enqueue(Q,14):
1
13
2
14
3
tail
7/1/2016
4
CS583 Fall'06: Basic Data Structures
7
Queue Algorithms
Enqueue(Q,x)
1 /* head and tail cannot point to the same
location,hence only (n-1) elements
can be stored */
2 if tail[Q] + 1 = head[Q]
3
throw "overflow"
4 Q[tail[Q]] = x
5 tail[Q] = tail[Q] % n + 1
// wrap around
7/1/2016
CS583 Fall'06: Basic Data Structures
8
Queue Algorithms (cont.)
Dequeue(Q)
1 if head[Q]=tail[Q]
2
throw "underflow"
3 x = Q[head[Q]]
4 head[Q] = head[Q] % n + 1
5 return x
// wrap around
Both operations run in O(1) time.
7/1/2016
CS583 Fall'06: Basic Data Structures
9
Linked Lists
• A linked list is a data structure in which objects are
arranged in linear order.
– Each object points to the location of the next object.
– In a doubly linked list each object also points to the
location of the previous object.
• More formally, for a doubly linked list L:
– head[L] points to the first element of the list.
– Given an element x from L:
•
•
•
•
7/1/2016
prev[x] points to its predecessor.
next[x] points to its successor.
If next[x] = NIL, x is the last element in L.
If prev[x] = NIL, x is the first element in L.
CS583 Fall'06: Basic Data Structures
10
Linked Lists Algorithms
The following algorithm finds the first element with key k in the list L:
List-Search(L,k)
1 x = head[L]
2 while x <> NIL and key[x] <> k
3
x = next[x]
4 return x
The above algorithm runs in (n) time in the worst case, since it may have to
search the entire list.
7/1/2016
CS583 Fall'06: Basic Data Structures
11
Linked Lists Algorithms (cont.)
The following algorithm inserts an element x with a key set to the front of the
list.
List-Insert(L,x)
1 next[x] = head[L]
2 if head[L] <> NIL
3
prev[head[L]] = x
4 head[L] = x
5 prev[x] = NIL
The running time of the insert algorithm is O(1).
7/1/2016
CS583 Fall'06: Basic Data Structures
12
Linked Lists Algorithms (cont.)
The following algorithm deletes an element x from the linked list. (It assumes
the pointer to x is known, otherwise use List-Search to find x according to
some key).
List-Delete(L,x)
1 if prev[x] <> NIL
2
next[prev[x]] = next[x]
3 else
4
head[L] = next[x]
5 if next[x] <> NIL
6
prev[next[x]] = prev[x]
This algorithm runs in O(1), however it would require (n) time if it needs to
search for an element.
7/1/2016
CS583 Fall'06: Basic Data Structures
13
Rooted Trees
• Trees can be represented using linked data structures.
– For example, in case of binary trees we use fields p, left, and right to
store pointers to the parent, left child, and right child of each node of
the binary tree T.
– The root of the tree is root[T] (x: p[x] = NIL).
• To represent trees with unbounded branching, we use binary
tree representation.
– In this scheme, each node still contains a parent pointer, and root[T]
points to the root of T. Instead of having a pointer for each child of a
node, each node x has only two pointers:
•
•
•
•
7/1/2016
left-child[x] points to the leftmost child of node x.
right-sibling[x] points to the sibling of x immediately to the right.
If node x has no children, then left-child[x] = NIL.
If node x is the rightmost child of its parent, then right-sibling[x] = NIL.
CS583 Fall'06: Basic Data Structures
14
Binary Search Tree
• Binary search tree is a binary tree that stores keys
and satellite data. The keys are stored in such a way
to satisfy the following property:
– Let x be a node in a BST. If y is a node in left subtree of x,
then key[y] <= key[x]. If y is a node in the right subtree
of x, then key[x] <= key[y].
• The above property allows us to print out all keys in
a BST in sorted order by an inorder tree walk
algorithm (left, root, right).
– Similar algorithms include preorder tree walk (root, left,
right), and postorder tree walk (left, right, root).
7/1/2016
CS583 Fall'06: Basic Data Structures
15
Inorder Tree Walk
Inorder-Tree-Walk (x)
1 if x <> NIL
2
Inorder-Tree-Walk(left[x])
3
print key[x]
4
Inorder-Tree-Walk(right[x])
It takes (n) to walk an n-node BST, since the procedure is called exactly
twice for each node of the tree (left and right child) + printing the node.
We prove it formally as follows.
Theorem 12.1
If x is the root of an n-node subtree, then Inorder-Tree-Walk(x) takes (n)
time.
7/1/2016
CS583 Fall'06: Basic Data Structures
16
Inorder Tree Walk: Performance
Proof.
On an empty subtree Inorder-Tree-Walk(x) takes a constant time (to compare
to NIL), so T(0) = c for some positive constant c.
For n>0, suppose the procedure is called on a node x, whose left subtree has k
nodes, and the right subtree has (n-k-1) nodes. The time to perform the
algorithm is:
T(n) = T(k) + T(n-k-1) + d,
where d is time to print x.
7/1/2016
CS583 Fall'06: Basic Data Structures
17
Inorder Tree Walk: Performance (cont.)
We use the substitution method to show that T(n) = (c+d)n + c. For n=0: T(0)
= c. For n>0 we have:
T(n) =
T(k) + T(n-k-1) + d =
((c+d)k + c) + ((c+d)(n-k-1) + c) + d =
ck + dk + c +cn –ck –c + dn –dk –d + c + d =
cn + dn + c =
(c+d)n + c 
7/1/2016
CS583 Fall'06: Basic Data Structures
18
BST: Querying
We use the following procedure to search for a node in BST:
Tree-Search(x,k)
Input: root x and key k
Output: pointer to a node with key k, or NIL if
not found
1 if x = NIL or k=key[x]
2
return x
3 if k < key[x]
4
return Tree-Search(left[x],k)
5 else
6
return Tree-Search(right[x],k)
The nodes encountered form a path downward from the root of the tree,
hence the running time of search is O(h), where h is the height of the tree.
7/1/2016
CS583 Fall'06: Basic Data Structures
19
BST: Minimum and Maximum
Minimum and maximum elements in BST can be found by following the
left, or the right subtree respectively:
Tree-Minimum(x)
1 while left[x] <> NIL
2
x = left[x]
3 return x
Tree-Maximum(x)
1 while right[x] <> NIL
2
x = right[x]
3 return x
7/1/2016
CS583 Fall'06: Basic Data Structures
20
BST: Finding Successor
If all keys are distinct, the successor of the node x is the smallest key
greater than key[x].
Tree-Successor(x)
1 if right[x] <> NIL
2
return Tree-Minimum(right[x])
3 y = parent[x]
4 while y <> NIL and x = right[y]
5
x = y
6
y = parent[y]
7 return y
When the right subtree is empty, the successor of x is the lowest ancestor of
x, whose left child is also ancestor of x (lines 3-7). To find such ancestor, we
find the first one that is not on the "right subtree" path to x.
The running time of the above algorithm is O(h) since we either follow a
path down or up from the node.
7/1/2016
CS583 Fall'06: Basic Data Structures
21
Download