Ordered Bag using a Sorted Array: Implementation and Complexity Analysis, Exams of Data Structures and Algorithms

An implementation of an ordered bag using a sorted array in c, along with an analysis of the algorithmic complexity of various operations such as contains, add, addat, remove, and removeat. The document also includes exercises for the reader to fill in the missing code and compare the performance of an ordered array bag with unordered dynamic array and linked list bags.

Typology: Exams

Pre 2010

Uploaded on 08/30/2009

koofers-user-9le-1
koofers-user-9le-1 🇺🇸

10 documents

1 / 4

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Worksheet 26: Ordered Bag using a Sorted Array Name:
An Active Learning Approach to Data Structures using C
1
Worksheet 26: Ordered Bag using a Sorted Array
In Preparation: Read Chapter 8 to learn more about the Bag data type and Chapter 9 to
learn more about the advantages of ordered collections. If you have not done it
previously, you should review Chapter 2 on the binary search algorithm, and do Lessons
14 and 16 to learn about the basic features of the dynamic array.
In an earlier lesson you encountered the binary search algorithm. The version shown
below takes as argument the value being tested, and returns, in O(log n) steps, either the
location at which the value is found, or if it is not in the collection the location the value
can be inserted and still preserve order.
Notice that the value
returned by this function
need not be a legal index. If
the test value is larger than
all the elements in the
array, the only position
where an insertion could be
performed and still preserve
order is the next index at
the top. Thus, the binary
search algorithm might
return a value equal to size,
which is not a legal index.
If we used a dynamic array as the underlying container, and if we kept the elements in
sorted order, then we could use the binary search algorithm to perform a very rapid
contains test. Simply call the binary search algorithm, and save the resulting index
position. Test that the index is legal; if it is, then test the value of the element stored at the
position. If it matches the test argument, then return true. Otherwise return false. Since
the binary search algorithm is O(log n), and all other operations are constant time, this
means that the contains test is O(log n), which is much faster than the bags developed in
Lessons 21 and 22.
Inserting a new value into the ordered array is not quite as easy. True, we can discover
the position where the insertion should be made by invoking the binary search algorithm.
But then what? Because the values are stored in a block, the problem is in many ways the
opposite of the one you examined in Lesson 21. Now, instead of moving values down to
delete an entry, we must here move values up to make a “hole” into which the new
element can be placed:
int binarySearch (EleType * data, int size, EleType testValue) {
int low = 0;
int high = size;
int mid;
while (low < high) {
mid = (low + high) / 2;
if (LT(data[mid], testValue))
low = mid + 1;
else
high = mid;
}
return low;
}
pf3
pf4

Partial preview of the text

Download Ordered Bag using a Sorted Array: Implementation and Complexity Analysis and more Exams Data Structures and Algorithms in PDF only on Docsity!

Worksheet 26: Ordered Bag using a Sorted Array

In Preparation : Read Chapter 8 to learn more about the Bag data type and Chapter 9 to learn more about the advantages of ordered collections. If you have not done it previously, you should review Chapter 2 on the binary search algorithm, and do Lessons 14 and 16 to learn about the basic features of the dynamic array. In an earlier lesson you encountered the binary search algorithm. The version shown below takes as argument the value being tested, and returns, in O(log n) steps, either the location at which the value is found, or if it is not in the collection the location the value can be inserted and still preserve order. Notice that the value returned by this function need not be a legal index. If the test value is larger than all the elements in the array, the only position where an insertion could be performed and still preserve order is the next index at the top. Thus, the binary search algorithm might return a value equal to size, which is not a legal index. If we used a dynamic array as the underlying container, and if we kept the elements in sorted order, then we could use the binary search algorithm to perform a very rapid contains test. Simply call the binary search algorithm, and save the resulting index position. Test that the index is legal; if it is, then test the value of the element stored at the position. If it matches the test argument, then return true. Otherwise return false. Since the binary search algorithm is O(log n), and all other operations are constant time, this means that the contains test is O(log n), which is much faster than the bags developed in Lessons 21 and 22. Inserting a new value into the ordered array is not quite as easy. True, we can discover the position where the insertion should be made by invoking the binary search algorithm. But then what? Because the values are stored in a block, the problem is in many ways the opposite of the one you examined in Lesson 21. Now, instead of moving values down to delete an entry, we must here move values up to make a “hole” into which the new element can be placed: int binarySearch (EleType * data, int size, EleType testValue) { int low = 0; int high = size; int mid; while (low < high) { mid = (low + high) / 2; if (LT(data[mid], testValue)) low = mid + 1; else high = mid; } return low; }

As we did with remove, we will divide this into two steps. The add method will find the correct location at which to insert a value, then call another method that will insert an element at a given location: void orderedArrayAdd (struct dyArray *da, EleType newElement) { int index = binarySearch(da->data, da->size, newElement); dyArrayAddAt (da, index, newElement); } The method addAt must check that the size is less than the capacity, calling dyArrayDoubleCapacity if not, loop over the elements in the array in order to open up a hole for the new value, insert the element into the hole, and finally update the variable count so that it correctly reflects the number of values in the container. void dyArrayAddAt (struct dyArray da, int index, EleType newElement) { int i; assert(index >= 0 && index <= da->size); if (da->size >= da->capacity) _dyArrayDoubleCapacity(da); … / you get to fill this in */ } The method remove could use the same implementation as you developed in Chapter B. However, whereas before we used a linear search to find the position of the value to be deleted, we can here use a binary search. If the index returned by binary search is a legal position, then invoke the function dyArrayRemoveAt that you wrote in Lessson X to remove the value at the indicated position.

On Your Own

Fill in the following Chart with the big-oh execution times for the simple unordered dynamic array bag (Lesson X), the linked list bag (Lesson x) and the ordered dynamic array bag (this worksheet). Dynamic Array Bag LinkedListBag Ordered Array Bag Push O( O( O( Top O( O( O( Pop O( O( O(

/* you must complete the following */ void orderedArrayAddAt (struct dyArray *dy, int index, EleType newElement) { int i; assert(index > 0 && index <= dy->size); if (dy->size >= dy->capacity) _dyArrayDoubleCapacity(dy); } int orderedArrayContains (struct dyArray *dy, EleType testElement) { } void orderedArrayRemove (struct dyArray *dy, EleType testElement) { }