adt Flashcards
(126 cards)
What methods: Stack Interface
1) pop
2) push
3) size
4) isEmpty
5) top
Describe push(o)
Inserts object o onto top of stack
Describe pop()
Removes the top object of stack and returns it
Describe size()
Returns the number of objects in stack
Describe isEmpty()
Return a boolean indicating if stack is empty.
Describe top()
Return the top object of the stack, without removing it
Name one limitation of a basic array implementation of a stack. What are some possible solutions?
In short:
The linked-list approach has worst-case O(1) guarantees on each operation; the dynamic array has amortized O(1) guarantees.
The locality of the linked list is not as good as the locality of the dynamic array.
The total overhead of the dynamic array is likely to be smaller than the total overhead of the linked list, assuming both store pointers to their elements.
The total overhead of the dynamic array is likely to be greater than that of the linked list if the elements are stored directly.
Neither of these structures is clearly “better” than the other. It really depends on your use case. The best way to figure out which is faster would be to time both and see which performs better.
What are the orders of the methods in the array based stack?
1) pop O(1)
2) push O(1)
3) size O(1)
4) isEmpty O(1)
5) top O(1)
What are the orders of the methods in linked-based stack
1) pop O(1)
2) push O(1)
3) size O(1)
4) isEmpty O(1)
5) top O(1)
What is the best implementation of a stack?Array or Linked-List? Explain
The linked list may be better because it doesn’t have a fixed size. Also, when the array-stack is made extensible it become less fast: pop() and push become O(n) vs. 0(1) in the linked-stack. The array based implementation will also need a block of free contiguous memory, whereas the linked list can be scattered around memory using references.
What are the Queue methods?
) Enqueue
2) Dequeue
3) Front
4) size
5) isEmpty
What are the orders of methods in linked-queue
All O(1)
What is a naive array-based queue?
Because the dequeue method leaves empty unused spaces behind it, it’s wasteful. The data continually crawls up along array moving to the right. The problem can be fixed by using a circular array
What is the formula for the size of a queue in a circular array?
Size = (N + rear - front) % N
What is a deque?
<p><p><p>Pronounced 'deck', it is a queue that allows insertion/deletion from either end of the queue.</p></p></p>
What are the methods of the deque?
1) insertFirst(o)
2) insertLast(o)
3) removeFirst()
4) removeLast()
5) size
6) isEmpty
7) front
8) rear
How can a dequeue be implemented?
1) Circular Array
2) Doubly Linked List
What is a vector?
Stacks and Queues are examples of ADTs that support insertion and removal at pre-specified points.
Stacks: insertion / removal at the top
Queues: insertion at the tail / removal at the head
Sequence ADT’s allow for insertion/removal anywhere in the data. A vector is just one type of sequence ADT and one which uses rank to access its elements.
What are the core methods of a vector ADT
1) elemAtRank(r)
2) replaceAtRank(r,e)
3) insertAtRank(r,e)
4) removeAtRank(r)
5) isEmpty()
6) size()
What are the orders of the methods in array based Vector ADT.
1) elemAtRank(r) O(1)
2) replaceAtRank(r,e) O(1)
3) insertAtRank(r,e) O(n) * not amortized
4) removeAtRank(r) O(n) * not amortized
5) isEmpty() O(1)
6) size() O(1)
What is the Order of inserting into an extendable array?
Despite having a loop, extendable arrays give amortized O(1) insertion, and not O(n). This is because when you spread the cost of all the operations out you find that it is possible (in theory) to save up operation-tokens such that you can afford a copying of the element into a bigger array.
What is better? A linked-list, or an array-based implementation of a vector?
The orders for a linked appraoch would be:
1) elemAtRank(r) O(n) * bad
2) replaceAtRank(r,e) O(n) * bad
3) insertAtRank(r,e) O(n)
4) removeAtRank(r) O(n)
5) isEmpty() O(1)
6) size() O(1)
For replaceAtRank and insertAtRank the need to shift elements has been replaced with the need to traverse them giving O(n) time. However, the need to traverse for
elemAtRank and replaceAtRank gives additional cost. Thus, the array based approach is superior, especially from an amortized perspective.
What are the operations of the list-based map adt
1) size()
2) isEmpty()
3) get(k)
4) put(k,v)
5) remove(k)
6) keys()
7) values()
8) entries()
How can we think of map, in terms of entries?
<p><p><p>You can think of a list based map as a list of entries. An entry is simply a single pairing of a key and value (K,V).</p></p></p>

Lets say don't want our hash map to require the use of an auxiliary data structure (list) so use the open addressing scheme as our collision strategy. What are our options within this scheme for dealing with collisions?

What is double hashing?
Double Hashing is an open addressing solution. If our original compression function (division method, mad method) results in a collision (the key already has a value) then we use a secondary hash function to probe the hash map until we find an empty bucket. Lets say our original compression function was i = h(k) giving our position in the hash map as a[i]. Following a collision, we now use h'(K) in the following way to probe for an empty bucket: a[ (i + j*h'(k)) % N] where j = 0,1,2,3,..... until a bucket is found (j allows probing) But how do we derive h'(k)? A common h'(k) is h'(k) = q - (k mod q) where q is a prime number smaller than N and remember, N must also be prime.
What is linear probing?
When a collision occurs you can probe along the map in ones until you find an empty. Later, when you wish to find this entry, you will probe in this linear fashion until you meet either k (found it), null (k doesn't exit), or N cells have been traversed (k doesn't exist).
What is a better collision strategy: open addressing or collision chaining?
Collision chaining is usually competitive or faster than alternative methods depending on the load factor of the bucket array? If memory is in short supply their may an argument for choosing an open address strategy.
What are the techniques used to traverse a tree?
What are the two parts of a hash function?
The hash code and the compression function? The hash code is the mapping of the key (which not be an int) into an integer. The compression function is what compresses these hash code intgers into a narrower range of integers.

List several common techniques of deriving hash codes from keys..
Describe load factor with reference to hash maps?
If a map has to store n entries into N buckets we hope to achieve a number of n/N entries in each bucket. This number is called the loading factor. For a set number of buckets, the speed of operations will slow down with the number of entries. To ensure a fast hash map the loading factor should be kept below some bound. A very low load factor is also wasteful (approaching zero) because it suggests their are too many empty buckets taking up memory.
What are some basic facts/rules about a tree?
Each element (node) in the tree has at most 1 parent. Each element (node) may have 0 or more children. Each tree will include exactly one element (node), known as the root, which has no parent.
Can a node in a tree have no parent?
Yes, the root will never have a parent
What are the methods for a tree structure?
Trees make use of the Position ADT and have the following operations: 11 in total: root() returns the Position for the root parent(p) returns the Position of p’s parent children(p) returns an Iterator of the Positions of p’s children isInternal(p) does p have children? isExternal(p) is p a leaf? isRoot(p) is p==root()? size() number of nodes isEmpty() tests whether or not the tree is empty iterator() returns an Iterator of every element in the tree positions() returns an Iterator of every Position in the tree replace(p, e) replaces the element at Position p with e
What are the properties of a binary tree?
A Binary Tree is a tree with the following properties: Every node has at most 2 children (degree 2) Each child node is labelled as being either a left child or a right child A left child precedes a right child in the ordering of children of a node
What is a "proper" binary tree?
A tree where all nodes have a degree = 0 or degree = 2
What are the techniques used to traverse a tree?
1) pre-order traversal 2) in-order traversal 3) post-order traversal 4) Euler traversal 5) breadth first traversal
What is a circular array and how can it be used to implement a queue?
What order are the nodes visited in for each of the following: 1) pre-order traversal 2) in-order traversal 3) post-order traversal 4) Euler traversal 5) breadth first traversal
1) pre-order traversal (root, left, right) (processed as the node is visited) 2) in-order traversal (Left, Root, Right) (Ascending) 3) post-order traversal (Left, Right, Root) (Node not processed till after its children) 4) Euler traversal These common traversals can be represented as a single algorithm by assuming that we visit each node three times. An Euler tour is a walk around the binary tree where each edge is treated as a wall, which you cannot cross. In this walk each node will be visited either on the left, or under the below, or on the right. The Euler tour in which we visit nodes on the left produces a preorder traversal. When we visit nodes from the below, we get an inorder traversal. And when we visit nodes on the right, we get a postorder traversal. 5) breadth first traversal
What properties must be satisfied for a binary search tree?
1) Each internal node holds a (unique) value. 2) A total-order relation (~) is defined on those values. * Reflexive: k ~ k * Antisymmetric: if k1 ~ k2 and k2 ~ k1 then k1 = k2 * Transitive: if k1 ~ k2 and k2 ~ k3 then k1 ~ k3 3) All the values (ki) in the left sub-tree of a node with value k satisfy the relation ki ~ k. 4) All the values (kj) in the right sub-tree of a node with value k satisfy the relation k ~ kj.
What is a useful feature of a binary search tree?
An in-order traversal of a binary search trees visits the values in the order specified by the total-order relation.
Binary Search trees support three main operations. What are they?
1) insert(e) 2) find(e) 3) remove(e)
Can we delete a node v with two children from a binary search tree bst?
Yes, but we must do the following: 1) we find the internal node w that follows v in an in-order traversal 2) we then copy w.element() into node v (cause v is going) 3) we then remove node w and its left child z (which must be a leaf)
What is the order of operations performed on a binary search tree?
In the worst case, when a tree of n nodes has a height of n, the order is O(N). But in a perfectly balanced tree the orderis O(log n)
Quick Recap. Turn over.
Trees are Hierarchical ADT’s in which data is defined in terms of parent and child relationships between nodes. A Proper Binary Tree is a Tree in which each node has either 0 (external) or 2 (internal) children. A Binary Search Tree is a Binary Tree that holds values whose location is determined by a total order relation. Binary Search Trees are another approach to implementing Maps and Dictionaries that have best case performance O(log n). Performance depends on the height of the tree, and is best when the tree is balanced.
What is special about AVL trees?
They are self-balancing. They achieve this by satisfying the height-balance property.
What is the height-balance property of an avl tree?
For every internal node v of T, the heights of the children of v can differ by at most 1.
What is the performance of an avl tree?
Because the tree is always balanced, the expected performance of this operation is O(log n)
What are Sequence ADTs?
ADTs that support insertion and removal at various points
What is the List ADT?
List ADT is a sequence data structure that abstracts the notion of a “place” in a list.
What is a position?
A position is a place in the list that a piece of data is stored.