CS31 Lab 6: Extra Challenge Problems
Do not try any of these until all the required parts of your lab 6 solution are implemented and fully tested; extra credit features with an incomplete or buggy required part will be worth much less than a fully working lab 6 solution with no extra credit features.

As an extra challenge try implementing remove_list and/or one of the two sorting functions:

/*********************************************************/
// remove_list:  removes the first instance of value in the list
//   list: the list to remove from (passed by reference)
//   value: the value to remove
//   returns: the index of the value removed or -1 if not found
//
//   this function has to shift all elements over by one
//   to fill the hole made by removing the element
//
int remove_list(plist list, void *value); 

/*********************************************************/
// sort 1 (the bad non-generic way):
//    sorts the elements in the given list by the given direction
//    list: the list to sort
//    direction: 0: increasing, non-zero: decreasing
//    sign: 0: unsigned values sort, non-zero: signed values sort
void bad_sort_list(plist list, int direction, int sign) ;
This sort function is by far more difficult than remove. Try implementing incrementally for different type data, and try signed before unsigned. You can implement any sorting algorithm (it does not need to be a fast sort...O(n^2) is fine). You may not use the stdlib qsort function to implement your sort.

sort (the bad way) is the one and only function where some kind of type information is needed to implement the correct comparison, which is why the sign parameter is passed in (and is why this is the bad way). A better way to implement sort is using a function pointer argument that takes a comparison function that is passed into sort by the caller, and is then called from within the library sort function:

/*********************************************************/
// sort 2 (the correct generic way):
//    sorts the elements in the given list by the given direction
//    list: the list to sort
//    direction: 0: increasing, non-zero: decreasing
//    compar: a pointer to a comparison function 
//             the comparison function should return:
//                           0: if values are equal
//                     positive: if first is greater than second
//                     negative: if first is less than second
void sort_list(plist list, int direction, int(*compar)( void *, void *)) ;
This is really the correct generic way to sort the plist values. This approach correctly keeps all type-specific code out of the plist library (the previous sort has to have an interanal comparison function(s) that use type information (size and signed) to do the comparison. With this implementation, a function pointer is used as the third parameter. A function with a matching prototpye can be passed to sort, and sort code can call this function through its function pointer parameter. The caller passes the name of (the address of) a funtion with a matching prototype. In the case of sorting, the user of the plist library will implement a comparison function to compare two values of the type that it knows it is storing in the plist buckets. The comparison function's prototype must match the function prototype of the third argument to sort, for example:
  int int_compare(void *value1, void *value2);
A call to sort would look like:
  sort(mylist, 0, int_compare);
From within the sort function in plist.c, the comparison function can be invoked through the function pointer paramter and passing arguments of the correct type:
  // you need the parens around (*compar) because of the lower
  // precedence of * vs. a function call (without the parens
  // the return value of the function call will be dereferenced)
  ret = (*compar)((void *)arg1, (void *)arg2);
See the man page for qsort for more information about function pointers. Again, you cannot just call qsort inside your sort implementation. I want you to implement the sorting algorithm of the underlying array of bytes. In fact, I want you to implement a "slow" O(n^2) algorithm such as insertion, selection or bubble sort.

handin

If you implement one or more of these functions, include calls to them in your testing code in main.c. Also, include a README file in your handin directory telling me which of these you implemented. There is no need to implement sort-the-bad-way if you implement sort-the-right-way.