下面的代码包括了四种常见的排序算法:归并排序(merge sort)快速排序(quick sort)大根堆排序(max root heap sort)和插入排序(insertion sort)
http://en.wikipedia.org/wiki/Sorting_algorithm#Stability
#include
#define ARRAY_SIZE 15
using namespace std;
typedef struct _node
{
int value_;
int index_;
}node;
void print_node(node* head, int size)
{
for (int ii = 0; ii < size; ++ii)
{
cout << "(" << head[ii].value_ << ", " << head[ii].index_ <<") ";
}
cout << endl;
}
/****************************************************************************************************************/
// brute force approach::insertion sort
// best case: Theta(n)
// worst case: Theta(n^2)
// average case: Theta(n^2)
// extra memory: Theta(1)
// stable
void insertion_sort(node* array, int size)
{
// start from the 2nd node
// please remember the index starts from 0
// enough if pseudo code starts from 1...
for (int ii = 1; ii < size; ++ii)
{
node tmp = array[ii];
int jj = ii - 1;
while ((jj > 0) && (array[jj].value_ > tmp.value_))
{
array[jj+1] = array[jj];
--jj;
}
array[jj+1] = tmp;
}
}
/****************************************************************************************************************/
// divide and conquer approach::merge sort
// best case:
// worst case:
// average case: Theta(n*log2(n))
// extra memory: Theta(n)
// stable
void merge(node * array, int head_1, int end_1, int rear )
{
node array_tmp[rear - head_1 + 1];
for (int ii = head_1; ii <= rear; ++ii)
{
array_tmp[ii - head_1] = array[ii];
}
int ii = head_1; // indicating the endpoint of the sorted part
int jj = head_1;
int kk = end_1 + 1; // jj kk indicate the start point of two subarrarys, respectively
while ((jj <= end_1) & (kk <= rear))
{
if (array_tmp[jj - head_1].value_ <= array_tmp[kk - head_1].value_)
{
array[ii] = array_tmp[jj - head_1];
++jj;
}else
{
array[ii] = array_tmp[kk - head_1];
++kk;
}
++ii;
}
// copying the remaining elements
if (jj > end_1)//the first subarray finished
{
while( kk <= rear )
{
array[ii++] = array_tmp[kk - head_1];
++kk;
}
}else // the first subarray has remaining elements
{
while( jj <= end_1 )
{
array[ii++] = array_tmp[jj - head_1];
++jj;
}
}
}
void merge_sort(node * array, int head, int rear)
{
if (head < rear)
{
int end_1 = (head + rear)/2;
merge_sort(array, head, end_1);
merge_sort(array, end_1+1, rear);
merge(array, head, end_1, rear);
}
}
/****************************************************************************************************************/
// divide and conquer approach::quick sort
// best case: O(nlog2(n)) array has already been divided evenly in half
// worst case: O(n^2) array has already been sorted
// avarage case: Theta(nlog2(n))
// extra memory: Theta(1)
// instability
int partition(node* array, int head, int rear)
{
node pivot_node = array[rear];
int ii = head - 1;
for (int jj = head; jj < rear; ++jj)
{
if (array[jj].value_ <= pivot_node.value_)
{
++ii;
node tmp = array[jj];
array[jj] = array[ii];
array[ii] = tmp;
}
}
node tmp = array[rear];
array[rear] = array[ii + 1];
array[ii + 1] = tmp;
return ii + 1;
}
void quick_sort(node* array, int head, int rear)
{
if (head < rear)
{
int pivot = partition(array, head, rear);
//the element at the position pivot is correct
//the half towards its left is smaller
quick_sort(array, head, pivot - 1);
//the half towards its right is bigger
quick_sort(array, pivot + 1, rear);
}
}
/****************************************************************************************************************/
// heapSort::max root
// best case: nlog2(n)
// worst case: nlog2(n)
// avarage case: nlog2(n)
// extra memory: Theta(1)
// instability
// for an element, finding its parent, left child, or right child
int parent(int index)
{
return index/2;
}
int left(int index)
{
return 2*index;
}
int right(int index)
{
return 2*index + 1;
}
// adjust until the subtree with root in index is a heap
void heapify(node* array, int size, int index)
{
int index_old;
do
{
index_old = index;
int child_left = left(index);
int child_right = right(index);
// find out which child is the max
if ((child_left < size) & (array[child_left].value_ > array[index].value_))
{
index = child_left;
}
if ((child_right < size) & (array[child_right].value_ > array[index].value_))
{
index = child_right;
}
// exchange
if (index != index_old)
{
node tmp = array[index];
array[index] = array[index_old];
array[index_old] = tmp;
}
}while(index != index_old);
}
void build_heap(node* array, int size)
{
for (int ii = size/2; ii >= 0; --ii)
{
heapify(array, size, ii);
}
}
void heap_sort(node* array, int size)
{
build_heap(array, size);
print_node(array, size);
for (int ii = size-1; ii > 0; --ii)
{
// put the root, which is the maximal value
// after build_heap, into the end of the array
// and decrease the size of the heap, so that
// the maximal value is excluded from the heap
node tmp = array[ii];
array[ii] = array[0];
array[0] = tmp;
--size;
heapify(array, size, 0);
}
}
/****************************************************************************************************************/
int main()
{
int value[ARRAY_SIZE] = {0,9,8,7,6,5,4,3,2,1,11,4,-65,4,6};
int index[ARRAY_SIZE] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
node N[ARRAY_SIZE];
for (int ii = 0; ii < ARRAY_SIZE; ++ii)
{
N[ii].value_ = value[ii];
N[ii].index_ = index[ii];
}
cout << "input : " << endl;
print_node(N, ARRAY_SIZE);
// choose a sorting
// insertion_sort(N, ARRAY_SIZE);
// merge_sort(N,0,ARRAY_SIZE);
// heap_sort(N, ARRAY_SIZE);
quick_sort(N, 0, ARRAY_SIZE-1);
cout << "output: " << endl;
print_node(N, ARRAY_SIZE);
}