【C++】排序算法小结

1、计数排序

如果给定上下界,并且区间不大的话,最适用。

比如对于英文字母数组进行排序。

时间复杂度O(n),空间复杂度O(n)

void countSort(int A[], int n, int low, int high)
{
    int size = high-low+1;
    vector<int> count(size, 0);    //count[i] represents low+i appears count[i] times in A
    for(int i = 0; i < n; i ++)
    {
        count[A[i]-low] ++;
    }
    int ind = 0;
    for(int i = 0; i < size; i ++)
    {
        while(count[i])
        {
            A[ind ++] = low+i;
            count[i] --;
        }
    }
}

 

2、冒泡排序(基础版)

最基础的排序算法,相邻元素两两比较并交换。

时间复杂度O(n2),空间复杂度O(1)。稳定排序。

void bubbleSort(int A[], int n)
{
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n-i-1; j ++)
        {
            if(A[j] > A[j+1])
                swap(A[j], A[j+1]);
        }
    }
}

 

3、冒泡排序(加速版)

如果中间结果已经有序,即一次遍历过程中不存在需要交换的相邻元素,则结束返回。

时间复杂度O(n2),空间复杂度O(1)。稳定排序。

void bubbleSortAc(int A[], int n)
{
    bool exchange;
    for(int i = 0; i < n; i ++)
    {
        exchange = false;
        for(int j = 0; j < n-i-1; j ++)
        {
            if(A[j] > A[j+1])
            {
                exchange = true;
                swap(A[j], A[j+1]);
            }
        }
        if(exchange == false)
            return;
    }
}

 

4、选择排序

遍历过程中选择最大元素,与末尾元素交换。

时间复杂度O(n2),空间复杂度O(1)。不稳定排序。

void selectSort(int A[], int n)
{
    for(int i = n-1; i >= 0; i --)
    {
        int max = A[0];
        int ind = 0;
        for(int j = 1; j <= i; j ++)
        {
            if(A[j] > max)
            {
                max = A[j];
                ind = j;
            }
        }
        if(ind != i)
            swap(A[ind], A[i]);
    }
}

 

5、插入排序

将当前元素插入局部有序的数组中。

时间复杂度O(n2),空间复杂度O(1)。稳定排序。

void insertSort(int A[], int n)
{
    for(int i = 1; i < n; i ++)
    {//insert A[i] into the right place
        int cur = i-1;
        int value = A[i];
        while(cur >= 0 && A[cur] > value)
        {
            A[cur+1] = A[cur];
            cur --;
        }
        A[cur+1] = value;
    }
}

 

6、快速排序

最常用的排序,使用pivot将数组分成大小两段,递归完成排序。

时间复杂度平均O(nlogn),最坏情况(已排序或逆序)O(n2),空间复杂度O(1)。不稳定排序。

int partition(int A[], int low, int high)
{
    int pivot = A[low];
    int vacant = low;
    while(low < high)
    {
        while(high > low && A[high] >= pivot)
            high --;
        //A[high] < pivot
        if(high > low)
        {
            A[vacant] = A[high];
            vacant = high;
        }
        else
            break;

        while(low < high && A[low] <= pivot)
            low ++;
        //A[low] > pivot
        if(low < high)
        {
            A[vacant] = A[low];
            vacant = low;
        }
        else
            break;
    }
    A[low] = pivot;
    return low;
}
void quickSort(int A[], int low, int high)
{
    if(low < high)
    {
        int pos = partition(A, low, high);
        quickSort(A, low, pos-1);
        quickSort(A, pos+1, high);
    }
}

 

7、堆排序

分为建堆与交换两个过程。

通常用于数组中寻找最大/小的k个元素。

时间复杂度O(nlogn),空间复杂度O(1)。不稳定排序。

void siftDown(int A[], int start, int end)
{
    int temp = A[start];
    int i = start;
    int j = 2*i + 1;    //left child
    while(j <= end)
    {
        if(j+1 <= end && A[j]<A[j+1])
            j = j+1;    //choose the bigger
        if(temp >= A[j])
            break;
        else
        {
            A[i] = A[j];
            i = j;
            j = 2*i + 1;
        }
    }
    A[i] = temp;
}
void heapSort(int A[], int n)
{
    //build max heap
    for(int i = (n-2)/2; i >= 0; i --)
        siftDown(A, i, n-1);

    //sort
    for(int i = n-1; i >= 0; i --)
    {
        swap(A[0], A[i]);
        siftDown(A, 0, i-1);    //not include the i_th node
    }
}

 

8、归并排序

分为局部排序与有序归并。

通常用于内存不足,需要与硬盘交互的排序。

时间复杂度O(nlogn),空间复杂度O(n)。稳定排序。

void merge(int A[], int start, int mid, int end)
{
    int size1 = mid-start+1;
    int* L = new int[size1];
    for(int i = 0; i < size1; i ++)
        L[i] = A[start+i];
    int size2 = end-mid;
    int* R = new int[size2];
    for(int i = 0; i < size2; i ++)
        R[i] = A[mid+1+i];
    
    int i = 0;
    int j = 0;
    int ind = start;
    while(i < size1 && j < size2)
    {
        if(L[i] <= R[j])
        {
            A[ind] = L[i];
            ind ++;
            i ++;
        }
        else
        {
            A[ind] = R[j];
            ind ++;
            j ++;
        }
    }
    while(i < size1)
    {
        A[ind] = L[i];
        ind ++;
        i ++;
    }
    while(j < size2)
    {
        A[ind] = R[j];
        ind ++;
        j ++;
    }
}
void mergeSort(int A[], int start, int end)
{
    if(start < end)
    {
        int mid = (start+end)/2;
        mergeSort(A, start, mid);
        mergeSort(A, mid+1, end);
        merge(A, start, mid, end);
    }
}

 

posted @ 2014-12-08 19:16  陆草纯  阅读(249)  评论(0编辑  收藏  举报