1) divide the list in half
2) perform mergesort on the left and right parts
3) merge the left and right parts back in order
Properties;
Best, Average and Worst case speed is O(nlog(n)).
Memory is n
It is Stable
//compile with g++ #include <iostream> #include <iomanip> using namespace std; void mergeSort(int* data, int* buffer, int size) { if(size < 2) return; int mid = size/2; mergeSort(data, buffer, mid); mergeSort(&data[mid], buffer, size - mid); int left = 0; int right = mid; int out = 0; while( (left != mid ) && (right != size) ) { if(data[right] < data[left]) { buffer[out++] = data[right++]; } else { buffer[out++] = data[left++]; } } while(left != mid ) { buffer[out++] = data[left++]; } while(right != size ) { buffer[out++] = data[right++]; } //transfer the buffer back to the main... small size sort so its better then doing mallocs all over the place out = 0; while(out != size ) { data[out] = buffer[out]; out++; } } //test #define SIZE 20 #define SCRAMBLE(x, y) ((0xa57b & ~y) + ((0x3829 & x) << 1)) bool check(int data[], int size) { for(int i = 1; i < size; i++) if(data[i] < data[i-1]) { cout << "FAIL!" << endl; return false; } cout << "PASS" << endl; return true; } void print(int data[], int size) { for(int i = 0; i < size; i++) cout << setw(5) << data[i] << " "; cout << endl; } bool test(int* data, int* buffer, int size) { print(data, SIZE); mergeSort(data, buffer, SIZE); print(data, SIZE); return check(data, SIZE); } int main() { int data[SIZE]; int buffer[SIZE]; bool pass = true; //easy data data[0] = 1; for(int i = 0; i < SIZE; i++) data[i] = SIZE - i; pass &= test(data, buffer, SIZE); //semi repeated data data[0] = 1; for(int i = 1; i < SIZE; i++) data[i] = SCRAMBLE(i, data[i-1]); pass &= test(data, buffer, SIZE); //the sort killer! for(int i = 0; i < SIZE; i++) data[i] = 5; pass &= test(data, buffer, SIZE); //and some randoms to catch anything i missed srand ( time(NULL) ); for(int j = 0; j < 100; j++) { for(int i = 0; i < SIZE; i++) data[i] = (int)((float)(j+1)*((float)rand()/(float)RAND_MAX)); pass &= test(data, buffer, SIZE); } if(pass) cout << "ALL PASSED" << endl; else cout << "FAILED" << endl; }
No comments:
Post a Comment