Week 10


Problem-Solving via Software1/41

Programming: solving problems by building software

The process:

  1. define the problem to be solved
  2. develop a method for solving it
  3. express the method as a software system
  4. check that it really solves the problem
  5. use the software to solve instances of the problem


... Problem-Solving via Software2/41

Computer science has its own jargon for these steps:

  1. specification: define the problem
  2. design: develop a method to solve it
  3. implementation: develop software
  4. testing: check the software
  5. deployment: use the software
We have looked at steps 3 and 4, but step 2 is also critical:


A Programmer's Toolkit3/41

What a programmer needs to know:


Problem-Solving Strategies4/41

Some questions which often perplex novice programmers:

The good news: The "bad" news:


... Problem-Solving Strategies5/41

We'll consider five basic strategies:

  1. solution by evolution
  2. divide and conquer
  3. generate and test
  4. simulation
  5. approximation techniques
All require you to "classify" the problem ...


Solution by Evolution6/41

Many problems you come across

Solution: adapt the previous solution   (yours or one from a book)

Example:

Essentially a kind of "argument by analogy".


... Solution by Evolution7/41

Assumptions in "solution by evolution":

This approach saves on design effort by re-using an existing design

The effort is spent on developing problem-specific operations


Exercise: Sorting8/41

Take the supplied program for sorting numbers (taken from function median(), week 6)


void sort(int array[], int n) {
        int i, min, marker;
        for (marker = 0; marker < n; marker++) {
		// find minimum between marker and n
                min = marker;
                for (i = marker+1; i < n; i++) {
                        if (array[i] < array[min]) {
				min = i;
			}
		}
		// swap element 'min' and 'marker'
                int tmp = array[marker];
                array[marker] = array[min];
		array[min] = tmp;
        }
}


Sorting Algorithms


Sorting Algorithms10/41

We will discuss three sorting algorithms


Selection Sort11/41

This is the sorting method we just saw.

Basic algorithm (based on arrays):

Example animation


... Selection Sort12/41


void selSort(int array[], int n) {  // an 'in place' sort so ...
	int i, min, marker;         // ... the array is 'overwritten'

	for (marker = 0; marker < n; marker++) {
		min = marker;       // assume element 'marker' is min
		for (i = marker+1; i < n; i++) {
			if (array[i] < array[min]) {
				min = i;  // found better min at 'i'
			}
		}
		int tmp;
		tmp = array[marker];
		array[marker] = array[min]; // swap elements 'min' ...
		array[min] = tmp;           // ... and 'marker'
	}
}


... Selection Sort13/41


3  6  5  2  4  1


1  6  5  2  4  3


1  2  5  6  4  3


1  2  3  6  4  5


1  2  3  4  6  5


1  2  3  4  5  6


Exercise: Performance of Selection Sort14/41

Measure performance of selection sort using the UNIX time command


... Exercise: Performance of Selection Sort15/41

Selection sort is typical of a class of quadratic algorithms

This is slower than linear algorithms (e.g. random number generation)


Selection Sort on Linked Lists16/41

Sort algorithms are usually implemented using arrays:

Sort algorithms can beimplemented on other data structures It depends on the sort algorithm whether this is very inefficient or not


... Selection Sort on Linked Lists17/41

In Selection Sort


Insertion Sort18/41

Often used by card players.

Basic algorithm:

Example animation


... Insertion Sort19/41


3  6  5  2  4  1


3  6  5  2  4  1


3  5  6  2  4  1


2  3  5  6  4  1


2  3  4  5  6  1


1  2  3  4  5  6


Exercise: Insertion Sort20/41

Implement insertion sort

void insertionSort(int array[], int n)

Measure performance of insertion sort using the UNIX time command


... Exercise: Insertion Sort21/41

If  array[i] >= array[i-1]

Hence, for ordered input


... Exercise: Insertion Sort22/41

If  array[i] < array[0]

Hence, for reversed input General formula: 1 + 2 + ... + (n-1) = n*(n-1)/2 = (n2-n)/2

Total number of comparisons is the same. Insertion sort is quadratic


Sorting with Stacks23/41

The quadratic sorts can also be implemented using stacks


... Sorting with Stacks24/41

Assume we have

Selection sort:
  1. pop the n numbers from A and push to B
  2. push the maximum number onto A
  3. pop the n-1 numbers from B and push them onto A
  4. let n = n-1 and repeat steps 1, 2 and 3 until n = 1
  5. A is now sorted (and B is of course empty)


... Sorting with Stacks25/41

[Diagram:Pic/stacksort-small.png]


Bubble Sort26/41

The simplest(?!) - but least efficient - of all sorting algorithms.

Video: Obama on Sorting Algorithms

Basic algorithm:

Example demo


... Bubble Sort27/41


void bubbleSort(int array[], int n) {
	int i, j;

	int earlyexit = 0;
	for (i = n-1; i > 0 && !earlyexit; i--) {
		earlyexit = 1;                         // assume no swaps needed    
		for (j = 1; j <= i; j++) { 
			if (array[j-1] > array[j]){
				int tmp = array[j];    // swap elements j and j-1
				array[j] = array[j-1];
				array[j-1] = tmp;
				earlyexit = 0;         // swap was required
			}
		}
	}
}


Exercise: Performance of Bubble Sort28/41

Measure performance of insertion sort using the UNIX time command


Quicksort


Problem-Solving Strategies30/41

Five basic problem-solving strategies:

  1. solution by evolution: adapt a known method
  2. divide and conquer: solve partial problem, then extend
  3. generate and test
  4. simulation
  5. approximation


Divide and Conquer31/41

In scenarios where:

then a divide and conquer strategy can be used.

Requires a systematic way of "reducing" the problem/data

and, ultimately, some way of handling the "base case"


... Divide and Conquer32/41

Comments on divide and conquer:


Exercise: Towers of Hanoi33/41

[Diagram:Pic/hanoi-small.png]

Use divide and conquer to design a recursive function


Quicksort34/41

Quicksort applies divide and conquer to sorting:

Example animation


... Quicksort35/41

Divide ...


int partition(int array[], int low, int high) {
	int pivot_item = array[low];
	int left = low, right = high;
	while (left < right) {
		// find leftmost element > pivot_item 
		while (array[left] <= pivot_item) {
			left++;
		}
		// find rightmost element < pivot_item 
		while (array[right] > pivot_item) {
			right--;
		}
		if (left < right) {
			int tmp = array[left]; // swap left and right       
			array[left] = array[right];
			array[right] = tmp;
		}
	}
	array[low] = array[right]; // right is final position for pivot
	array[right] = pivot_item;
	return right;
}


... Quicksort36/41

... and Conquer!


void quicksort(int array[], int low, int high) {
	int pivot;
	if (high > low) {       // termination condition low >= high  
		pivot = partition(array, low, high);
		quicksort(array, low, pivot-1);
		quicksort(array, pivot+1, high);
	}
}


... Quicksort37/41


3  6  5  2  4  1


3  1  5  2  4  6


3  1  2  5  4  6


2  1   | 3 |   6  4  5


1  2   | 3 |   6  4  5


1  2   | 3 |   5  4   | 6 |


1  2   | 3 |   4  5   | 6 |


Exercise: Performance of Quicksort38/41

Measure performance of quicksort using the UNIX time command


... Exercise: Performance of Quicksort39/41

This is much faster than quadratic algorithms (e.g. slection sort, insertion sort)


Comparison of Sorting Algorithms40/41

[Diagram:Pic/comparison-small.png]


Tips for Next Week's Lab41/41


Sorting with different data structures


Produced: 12 Oct 2016