四种常见的基于比较的排序算法C++

下面的代码包括了四种常见的排序算法:归并排序(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);
}
 
  

你可能感兴趣的:(C++,数据结构)