C343 - Data Structures and Algorithms Final
Two Conditions of Binary Search Trees
1) All nodes in the left subtree of a node must be less than the parent node 2) All nodes in the right subtree of a node must be greater than the parent node
Max Heap Insertion Steps
1. Add new value to Heap, add to end of array. 2. If new value is greater than parent, swap with parent. 3. Do this iteratively until new value reaches correct position.
Building a Huffman Tree
1. Sort the table based on frequency 2. Choose the two smallest numbers - Smaller number goes on the left, larger on the right 3. Merge them and reorder list iteratively until all values are combined.
Heap Removal Steps
1. Swap the first element with the last element 2. Remove Last Element 3. Fix Heap using siftDown() (take θ(long)) Removes max value from a max heap and the min value from a min heap
Properties of Heaps
A complete binary tree, almost always implements as an array for complete binary trees Values stored are partially ordered, there is a relationship between the value of a node and the values of its children.
Complete Binary Tree
A tree where all levels except possibly the last is completely filled
Time Comparison of Array Based List VS Linked List Access
Array Based List: θ(1) Linked List: θ(n) Array Based Lists are faster
Time Comparison of Array Based List VS Linked List Insertion and Deletion
Array Based List: θ(n) Linked List: θ(1) Linked Lists are faster
Time Comparison of Array Based List VS Linked List Search
Array Based List: θ(n) Linked List: θ(n) No Benefit for Either
Heap Sort
Based on Heap data structure Not as fast as Quick Sort in the average case (by constant factor), but still used in some applications such as graphs.
Limitations of Bin Sort
Can't process duplicates Needs an array as large as the largest key Number of comparisons grow with he largest value in array, not by number of values in the array.
Closed Hashing
Collision Resolution goal is to find a free slot in the hash table when the home position is taken. Function p has two parameters: Key k and count i
Insertion Sort
Compares the first two elements, sorts, then adds the variables. Good when data is almost sorted
Merge Sort
Divide and Conquer Breaking the list to be sorted into pieces, process the pieces, and then putting them back together.
Full Binary Tree
Each node is either an internal node with two non-empty children, or a lead. (No node can have just one child)
Max Heap
Every node stores a value that is greater than or equal to that of its children Highest value is the root node Useful from finding the maximum, but not efficient when searching for values.
Min Heap
Every node stores a value that is less than or equal to that of its children. Lowest value is the root node
Hash Binning
Example: Given keys in range 0 - 999, and have a hash table of size 10. In this case, you simply divide the key value by 100. (1000/10) Divide amount of keys by size of table
Properties of Queues
FIFO - First In First Out Front = Pointer to the first element in the queue Rear = Pointer to the last element in the queue
Selection Sort
Finds the largest key in unsorted list, then next largest, and so on. Few record swaps
Decoding a Huffman Tree
For each bit in the Huffman Code: 0 = Left Branch 1 = Right Branch
Pseudo-Random Probing
Given a permutation: a list of integers that tells how many places to skip M = size of table r1 is the i-th value in a random permutation of the numbers from 1 to M-1 Probe sequence: (h(k) + ri) % M Eliminates primary clustering but not secondary clustering.
Properties of a Stack
LIFO - Last In First Out Top Variable = The Accessible Element of the Stack
Postorder Traversal
Left, Right, Root
Inorder Traversal
Left, Root, Right
Merge Sort Algorithm
List mergeSort(List inList) { if(inList.length() <= 1) { return inList; } List L1 = half of the items from inList; List L2 = other half of the items from inList; return merge(mergeSort(L1), mergeSort(L2)); } List merge(List L1, List L2) { List answer = new List(); while(L1 != NULL || L2 != NULL) { if(L2 == NULL) { answer.append(L2); L2 = NULL; } else if(L2 == NULL) { answer.append(L1); L1 = NULL; } else if(L1.value() <= L2.value()) { answer.append(L1.value()); L1 = L1.next(); } else { answer.append(L2.value()); L2 = L2.next(); } } return answer; }
Overall Time Comparison of Array Based List VS Linked List
Overall, Linked Lists are preferred due to insertion and deletion being most dominate.
Shell Sort
Performs insertion on sublists. First on small sublists then increasingly larger sublists.
Binary Tree Overhead
Pointer Size P Data Object Size D Regular Binary Tree: Total Space Taken By Overhead = 2P/(2P+D) Full Binary Tree: Total Space Taken By Overhead = P/(P+D)
Linear Probing
Probe Function: p(k, i) = i If home position is taken, then go to the next available spot (increments by 1) Leads to primary clustering, very bad choice
Preorder Traversal
Root, Left, Right
Open Hashing
Simplest form of open hashing defines each slot in the hash table to be the head of a linked list.
Radix Sort
Sorts based on the base 10 of the number Processes records with k digit keys in k passes, where each pass sorts the records according to the current digit. Efficient when the number of digits is small compared to the number of records if the n records all have unique key values, then at least Ω(long) digits are required, leading to an Ω(blown) sorting algorithm Tends to be much slower than Quick Sort and Merge Sort
Hash Mid-Square Method
Squares the key value, then takes out middle r bits of the result. Works well since most or all bits of the key value contribute to the result (unlike mod or binning)
Linear Probing by Steps
Using linear probing but skipping some slots Probe Function: p(k, i) = ci Constant c must be relatively prime to size of table to visit all slots in the table.
Functions of Queues
enqueue() - Adding variable to the end of the queue and assigning the rear value to it (As long as the queue is not full) dequeue() - Deleting and returning the front (first) element in the queue
Simple Bin Sort Algorithm
for(i = 0; i < A.length; i++) { B[A[i]] = A[i]; }
Selection Sort Algorithm
for(int i = 0; i < A.length-1; i++){ int bigIndex = 0; for(int j = 1; j < A.length-i; j++) { if(A[j].compareTo(A[bigIndex]) > 0) { bigIndex = j; } } Swap.swap(A, bigIndex, A.length-i-1); }
Insertion Sort Algorithm
for(int i = 1; i < A.length; i++){ for(int j = 1; (j > 0) && {A[j].compareTo(A[j-1]) < 0); j--){ Swap.swap(A, j, j-1); } }
Hash Mod Function
int h(int x) { return x % 16; }
Functions of a Stack
pop() - Takes the last item in the stack and returns it push() - Adds the item to the end of stack
BST Insertion Implementation
private BSTNode insert help(BSTNode rt, Comparable e){ if(rt == null){ return new BSTNode(e); } if(rt.value().compareTo(e) >= 0){ rt.setLeft(insert help(rt.left(), e)); } else{ rt.setRight(insert help(rt.right(), e)); } return rt; }
BST Deletion Implementation
private BSTNode removehelp(BSTNode rt, Comparable key){ if(rt == null){ return null; } if(rt.value().compareTo(key) > 0){ rt.setLeft(removehelp(rt.left(), key)); } else if(rt.value().compareTo(key) < 0) { rt.setRight(removehelp(rt.right(), key)); } else { if(rt.left() == null){ return rt.right(); } else if(rt.right() == null){ return rt.left(); } else { BSTNode temp = getmax(rt.left()); rt.setValue(temp.value()); rt.setLeft(deletemax(rt.left())); } } return rt; }
Bubble Sort Algorithm
static <T extends Comparable<T>> void bubble sort(T[ ] A) { for(int i = 0; i < A.length-1; i++) { for(int j = 1; j < A.length-i; j++){ if(A[j-1].compareTo(A[j]) > 0) { Swap.swap(A, j-1, j); } } } }
Quick Sort Algorithm
static int findPivot(Comparable[ ] A, int i, int j) { return (i + j) / 2; } static void quickSort(Comparable[ ] A, int i, int j) { int pivotIndex = findPivot(A, i, j); Swap.swap(A, pivotIndex, j); int k = partition(A, i, j-1, A[j]); Swap.swap(A, k, j); if((k - i) > 1) { quickSort(A, i, k-1); } if((j - k) > 1) { quickSort(A, k+1, j); } static int partition(Comparable[ ] A, int left, int right, Comparable pivot) { while( left <= right) { while(A[left].compareTo(pivot) < 0) { left++; } while((right >= left) && (A[right].compareTo(pivot) >= 0) { right--; } if(right > left) { Swap.swap(A, left, right); } } return left; }
Bin Sort Algorithm Modified to Hold Duplicates
static void binSort(int[ ] A) { List[ ] B = new LinkedList[MaxKeyValue + 1]; int item; for(int i = 0; i <= MaxKeyValue; i++) { B[i] = new LinkedList(); } for(int i = 0; i < A.length; i++) { B[A[i]].append(A[i]); } int pos = 0; for(int i = 0; i < MaxKeyValue; I++) { for(B[I].moveToStart(); (item = B[I].getValue()) != -1; B[I].next()) { A[pos++] = item; } } }
Heap Sort Algorithm
static void heapSort(Comparable[ ] A) { MaxHeap H = new MaxHeap(A, A.length, A.length); for(int i = 0; i < A.length; i++){ H.removemax(); } }
Radix Sort Algorithm
static void radix(Integer[ ] A, int k, int r) { Integer[ ] B = new Integer[A.length]; int[ ] count = new int[r]; int i, j, rtok; for(i = 0; rtok = 1; i < k; i++; rtok *= r) { for(j = 0; j < r; j++) { count[j] = 0; } for(j = 0; j < A.length; j++) { count[(A[j]/rtok)%r]++; } count[0] = count[0] - 1; for(j = 1; j < r; j++) { count[j] = count[j-1] + count[j]; } for(j = A.length-1; j >= 0; j--) { B[count[(A[j]/rtok)%r]] = A[j]; count[(A[j]/rtok)%r] -1; } for(j = 0; j < A.length; j++) { A[j] = B[j]; } } }
Shell Sort Algorithm
static void shell sort(int[ ] A) { for(int i = A.length/2; i > 2; i/=2) { for(int j = 0; j < I; j++) { insSort2(A, j, i); } } insSort2(A, 0, 1); } static void insSort2(int[ ] A, int start, int incr) { for(int i = start + incr; i < A.length; i += incr) { for(int j = I; (j >= incr) && (A[j] < A[j-incr]); j -= incr) { Swap.swap(A, j, j - incr); } } }
Time Complexity of Array Access
θ(1)
Time Complexity of Linked List Deletion
θ(1)
Time Complexity of Linked List Insertion
θ(1)
Time Complexity of Queue Deletion
θ(1)
Time Complexity of Queue Insertion
θ(1)
Time Complexity of Stack Deletion
θ(1)
Time Complexity of Stack Insertion
θ(1)
Best/Average Case of BST Access
θ(log(n))
Best/Average Case of BST Deletion
θ(log(n))
Best/Average Case of BST Insertion
θ(log(n))
Best/Average Case of Searching a BST
θ(log(n))
Worst Case Time Complexity of Heap Insertion
θ(logn)
Worst/Average Case Time Complexity of Heap Removal
θ(logn)
Best Case Time Complexity for Insertion Sort
θ(n)
Time Complexity of Array Deletion
θ(n)
Time Complexity of Array Insertion
θ(n)
Time Complexity of Linked List Access
θ(n)
Time Complexity of Queue Access
θ(n)
Time Complexity of Searching a Linked List
θ(n)
Time Complexity of Searching a Queue
θ(n)
Time Complexity of Searching a Stack
θ(n)
Time Complexity of Searching an Array
θ(n)
Time Complexity of Stack Access
θ(n)
Worst Case of BST Access
θ(n)
Worst Case of BST Deletion
θ(n)
Worst Case of BST Insertion
θ(n)
Worst Case of Searching a BST
θ(n)
Average Case Time Complexity of Bin Sort
θ(n+K)
Best Case Time Complexity of Bin Sort
θ(n+K)
Worst Case Time Complexity of Bin Sort
θ(n+K)
Average Case Time Complexity of Radix Sort
θ(nK)
Best Case Time Complexity of Radix Sort
θ(nK)
Worst Case Time Complexity of Radix Sort
θ(nK)
Average Case Time Complexity of Shell Sort
θ(n^1.5) or θ(n SqRt n)
Average Case Time Complexity for Insertion Sort
θ(n^2)
Average Case Time Complexity of Selection Sort
θ(n^2)
Best case Time Complexity of Selection Sort
θ(n^2)
Bubble Sort Average Case Time Complexity
θ(n^2)
Bubble Sort Best Case Time Complexity
θ(n^2)
Bubble Sort Worse Case Time Complexity
θ(n^2)
Worst Case Time Complexity for Insertion Sort
θ(n^2)
Worst Case Time Complexity of Quick Sort
θ(n^2)
Worst Case Time Complexity of Selection Sort
θ(n^2)
Average Case Time Complexity of Heap Sort
θ(nlogn)
Average Case Time Complexity of Merge Sort
θ(nlogn)
Average Case Time Complexity of Quick Sort
θ(nlogn)
Best Case Time Complexity of Heap Sort
θ(nlogn)
Best Case Time Complexity of Merge Sort
θ(nlogn)
Best Case Time Complexity of Quick Sort
θ(nlogn)
Worst Case Time Complexity of Heap Sort
θ(nlogn)
Worst Case Time Complexity of Merge Sort
θ(nlogn)