1 / 40

Data Structures Unsorted Arrays

Explore the fundamentals, considerations, and functional application of arrays in programming, with insights into insertion algorithms and performance analysis. Learn how to optimize array append and insert operations for efficiency.

shawnd
Download Presentation

Data Structures Unsorted Arrays

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Data StructuresUnsorted Arrays Phil Tayco Slide version 1.2 Feb 1, 2019

  2. Arrays Our first traditional data structure • Arrays in modern programming languages have different forms (ArrayList, dynamic memory allocated arrays, dictionaries, etc.) • Depending on the language, many of the constraints we discuss may appear to be addressed • We look at a more traditional view of an array and its design intentions versus a specific programming languages implementation

  3. Arrays Definition • This structure begins with reserving a specified amount of space for n number of elements • Each element is the same data type • Direct random access of any element is possible • Element location is referred to as an “index” with the first index starting at a value of 0 • Example, an array of 6 integers: 6 1 4 3 8 5 0 1 2 3 4 5

  4. Arrays Considerations • A specified amount of space for n number of elements must be reserved. This means you must consider maximum capacity at creation and implies some space may not be used in the program • Direct random access of any element is possible suggesting fast performance getting to any data element • Array structure theory can apply to other similar types of situations (spaces in a egg carton, books on a shelf, etc.)

  5. Arrays Functional usage: Insert Adding an element into an array requires 2 essential steps Ensuring there is enough space in the array to add the new record Adding the record while preserving the intended order of the array Many times, an additional variable representing current size is maintained along with the array (e.g. the capacity of an array may be set to 100 but the current number of existing elements may be 5)

  6. Arrays Insert unordered 1: append If the order is insignificant, the key step after ensuring there is enough space is to find the next available space and adding the new record there An effective way to maintain this is to use the current size variable as the index for the next available space to add a record Before append, if the current size is already equal to the array capacity, the append cannot be performed If insert is performed, the current size must be incremented

  7. Arrays Sample code for append unordered: // Given int[] numbers = new int[100]; // Given int currentSize = 0; boolean append(int element) { if (currentSize == numbers.length) return false; // Array is at maximum capacity numbers[currentSize++] = element; return true; }

  8. Arrays array before append: array after append(5); 6 1 4 currentsize 3 0 1 2 3 4 5 6 1 4 5 currentsize 4 0 1 2 3 4 5

  9. Arrays Append unordered analysis Using the comparison operation type and a worst case scenario of all elements filled, the order for this algorithm is O(1) since there will always be a comparison performed The performance is also the same in all other cases (if the list is empty or partially full) If the array is unordered, this algorithm is most effective given that its performance is constant Question: Would it even be possible to eliminate the need to perform a comparison? Question: What are we assuming about “holes” in the array?

  10. Arrays Examine another insert methods? Given this ideal performance, it may seem unnecessary to explore other algorithms As analysts on the never ending quest for something better, we should take a look at other ideas Using Big-O to show another algorithms performance gives definitive proof of the effectiveness of one approach compared against another

  11. Arrays Insert unordered algorithm 2: insertFront In the previous algorithm, the new element gets added to the end of the array What if we added it to the beginning of the array? All elements “in front” of the new record must be shifted over to the next spot The need to check for capacity must still be performed

  12. Arrays array before insert: array after insert(5); 6 1 4 currentsize 3 0 1 2 3 4 5 5 6 1 4 currentsize 4 0 1 2 3 4 5

  13. Arrays Sample code for insert unordered 2: boolean insertFront(Type element) { if (currentSize == numbers.length) return false; // Array is at maximum capacity for (int n = currentSize; n > 0 ; n--) numbers[n] = numbers[n-1]; numbers[0] = element; currentSize++; return true; }

  14. Arrays insertFront unordered analysis The code starts the same as append with the capacity check and then contains additional code for the shift (a loop) Append’s performance is consistent in worst and best case scenarios What are the best and worst case scenarios here? What are the Big-Os for these scenarios?

  15. Arrays insertFront unordered analysis Best cases are O(1) performance because the array is either empty or full and the loop to shift elements does not occur Worst case performance is O(n) when only one space is available and the loop must perform (n-1) comparisons to shift everything before adding the new record Compared to append, insertFront degrades from O(1) to O(n) when viewing from best to worst case. Append is always O(1) no matter the scenario

  16. Arrays Insert unordered algorithms comparison Clearly, the first algorithm is preferred. Does that mean the second algorithm has no application? Is there anything to be learned from the second algorithm? A pattern we should notice is that a shifting of elements implies an O(n) performance Next, we look at the Search and Update functions

  17. Arrays Search As discussed in the introduction, the search in an unordered list is an O(n) operation in the worst case using comparisons as the operation type Worst case situation is the record is found in the last location or does not exist in a full array Best case is the record is found on the first try

  18. Arrays Linear Search Since the algorithm performs at O(n), an unordered array search is often referred to as a “Linear search” Sample code that follows returns the index location of the record if found or -1 representing not found

  19. Arrays Sample code for linear search: int linearSearch(int element) { for (int n = 0; n < currentSize; n++) if (numbers[n] == element) return n; return -1; }

  20. Arrays search(4): search(3); 6 1 4 5 Returns 2 0 1 2 3 4 5 6 1 4 5 Returns -1 0 1 2 3 4 5

  21. Arrays Linear search analysis Clearly, this is O(n) performance. However, notice the actual number of comparisons 1 comparison to control the loop 1 comparison to check between element and array index The actual number of comparisons in the worst case is 2 * n. Why isn’t this referred to as O(2n)? Our initial analysis is to identify the algorithm category If we want to compare between two O(n) algorithms, the 2n becomes more significant

  22. Arrays Can we do better? The inclination is to see if we can develop an algorithm that performs better than this Significantly better means a better category of performance. For linear search, O(log n) and O(1) are the only ones better than O(n) As discussed in the introduction slides, because the content of the array is unordered, we have to check every element in the worst case making it impossible for linear search to achieve O(1) or O(log n)

  23. Arrays Unordered search is linear search As much as we want to develop an algorithm that performs better than O(n), there are challenges: Worst case requires going through every single element in the array Arbitrary start points (end of array or middle of array) and random hopping around the array do not improve the performance in the worst case and actually make things more complicated Think of a word search puzzle. If your algorithm is to look for the first letter of your search word in the puzzle, no matter how you jump around, the worst case is still ending up checking every letter

  24. Arrays Update The search algorithm has a significant implication with update (and delete) Update is a search for an element and if found, modifying it while maintaining the design intent of the structure In this case, the design intent is an unordered list making a modification of a record simple (there’s no need to check if the array order needs to be maintained because there is no order) We can use the search algorithm in our update

  25. Arrays Sample code for update: boolean update(int oldValue, int newValue) { int searchIndex = linearSearch(oldValue); if (searchIndex == -1) return false; // Element to update is not found numbers[searchIndex] = newValue; return true; }

  26. Arrays Before update (3, 4): After update(3, 4); 6 1 3 5 0 1 2 3 4 5 6 1 4 5 Returns true 0 1 2 3 4 5

  27. Arrays Update analysis Because the algorithm uses the search algorithm, the performance initially depends on the Big O of the search Since the search is linear in the worst case, update performance will at least be O(n) as well Are there additional comparisons to consider? Notice after search is performed, there is one more comparison done to check if the record was found Technically, this algorithm is O(2n + 1), but as far as a category is concerned, this is still O(n) Thus, the update performance is also linear in the worst case

  28. Arrays Delete Now the delete. In most data structures, the delete function is usually found to be the most complex and is often treated last among the 4 functions The design intent of this structure is still unordered, so maintaining order after removing an element is considered With any maintenance function performed (delete, insert and update), we must consider the impact to the other functions such that their algorithms still perform as expected

  29. Arrays Basic search and delete of 3: After basic search and delete of 3 currentSize = 4 6 1 3 5 0 1 2 3 4 5 6 1 5 currentSize = 3 0 1 2 3 4 5

  30. Arrays Hole-y Toledo! We must avoid having “holes” in the array because that impacts the use of the “currentSize” variable as the location of the next available element Fixing this hole in requires the following to consider: The integrity of the data structure must be maintained The “currentSize” variable must be appropriately updated

  31. Arrays A shifty approach One algorithm could use the following steps: Use the search algorithm to find the element to remove Shift over “to the left” any records after the record Reduce the current size by 1

  32. Arrays Search in delete(3): Shift at end of delete(3): currentSize = 5 6 1 3 5 2 0 1 2 3 4 5 6 1 5 2 currentSize = 4 0 1 2 3 4 5

  33. Arrays Sample code for delete: boolean deleteShift(int element) { int searchIndex = linearSearch(element); if (searchIndex == -1) return false; // Element to update is not found for (int n = searchIndex; n < currentSize - 1; n++) numbers[n] = numbers[n+1]; numbers[currentSize] = -1; // “Remove” last element currentSize--; }

  34. Arrays deleteShift analysis Because the algorithm uses the search algorithm, the performance initially depends on the Big O of the search However, we must also consider the performance of the shift that occurs after the search This always leads to a performance of O(n) in the worst cases: Best case search is worst case shift (first element deleted requiring shifting of elements in a full array) Best case shift is worst case search (nothing to shift, but element search is last in array)

  35. Arrays deleteMove algorithm We can actually avoid the use of shifts to fix the hole by taking advantage of the fact that the array is unordered Movethe last element in the array (at the “currentSize” index location - 1) to the spot where the element was removed Reduce the current size by 1

  36. Arrays Search in delete(3): Move at end of delete(3): currentSize = 5 6 1 3 5 2 0 1 2 3 4 5 6 1 2 5 currentSize = 4 0 1 2 3 4 5

  37. Arrays Sample code for 2nd delete: booleandeleteMove(int element) { intsearchIndex = linearSearch(element); if (searchIndex == -1) return false; // Element to update is not found numbers[searchIndex] = numbers[currentSize - 1]; numbers[currentSize - 1] = -1; // “Remove” last element of array currentSize--; return true; }

  38. Arrays That worst case scenario though… For best and average cases, deleteMove runs faster than deleteShift The worst case of the delete is still O(n) because of the linear search For both delete algorithms, the worst case is O(n). Since they are in the same Big-O category, we can dig deeper: Worst case search for both algorithms is O(n) Worst case shift in the first algorithm is best case for deleteMove In such cases, no matter how large the array is, if the element deleted is at or near the first element, deleteMove is better than shift

  39. Arrays Duplicates As we look at more data structures and algorithms, the question of how duplicate values are handled will recur and is important to consider Duplicate values imply there is no difference between elements (if two elements have the same key value, they’re not really different elements) As such, selecting between duplicate elements is arbitrary. If you have two elements with the same value, it should not matter which one you find in your algorithm Thus, for the search, insert, update and delete algorithms, duplicate values do not impact their performance

  40. Arrays Unordered Array Summary Worst case scenarios show the performances as: Insert: O(1) Update, Search and Delete: O(n) Holes are not intended in this data structure to ensure the currentSize variable is utilized properly Update and Delete are dependent on Search – if Search were somehow improved, Update and Delete could be positively impacted Search is improved dramatically if a sense of order is maintained. This is our next topic: Sorted arrays

More Related