【C/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);
    }
}
时间: 2024-10-12 16:13:50

【C/C++】排序算法小结的相关文章

排序算法小结

排序算法经过了很长时间的演变,产生了很多种不同的方法.对于初学者来说,对它们进行整理便于理解记忆显得很重要.每种算法都有它特定的使用场合,很难通用.因此,我们很有必要对所有常见的排序算法进行归纳. 我不喜欢死记硬背,我更偏向于弄清来龙去脉,理解性地记忆.比如下面这张图,我们将围绕这张图来思考几个问题. 上面的这张图来自一个PPT.它概括了数据结构中的所有常见的排序算法.现在有以下几个问题: 1.每个算法的思想是什么?     2.每个算法的稳定性怎样?时间复杂度是多少?     3.在什么情况下

常见排序算法小结

排序算法经过了很长时间的演变,产生了很多种不同的方法.对于初学者来说,对它们进行整理便于理解记忆显得很重要.每种算法都有它特定的使用场合,很难通用.因此,我们很有必要对所有常见的排序算法进行归纳. 我不喜欢死记硬背,我更偏向于弄清来龙去脉,理解性地记忆.比如下面这张图,我们将围绕这张图来思考几个问题. 上面的这张图来自一个PPT.它概括了数据结构中的所有常见的排序算法.现在有以下几个问题: 1.每个算法的思想是什么?      2.每个算法的稳定性怎样?时间复杂度是多少?      3.在什么情

【转】排序算法小结

排序算法经过了很长时间的演变,产生了很多种不同的方法.对于初学者来说,对它们进行整理便于理解记忆显得很重要.每种算法都有它特定的使用场合,很难通用.因此,我们很有必要对所有常见的排序算法进行归纳. 我不喜欢死记硬背,我更偏向于弄清来龙去脉,理解性地记忆.比如下面这张图,我们将围绕这张图来思考几个问题. 上面的这张图来自一个PPT.它概括了数据结构中的所有常见的排序算法.现在有以下几个问题: 1.每个算法的思想是什么?      2.每个算法的稳定性怎样?时间复杂度是多少?      3.在什么情

常用排序算法小结

1 #include <stdio.h> 2 #include <stdlib.h> 3 4 5 //the basic bubble sort 6 void maopao1(int *num,int len) 7 { 8 int i,j; 9 int temp; 10 for (i = 0; i < len-1; ++i) 11 { 12 for (j = i+1; j<len; ++j) 13 { 14 if (num[i]>num[j]) 15 { 16 t

各种排序算法小结和实现

各种排序算法想必大家都不陌生,定义我就不多介绍了,直接写下自己的一些小结. 快速排序:可以算的上应用最广的排序算法.其排序思路是随机选取一个数字作为标志,使得小于它的数在它左边,大于它的数在它的右边,然后递归对两边的数据排序. 归并排序:应用分之的思想,先将要排序的分为两列,然后分别进行排序,然后合并到另一 个数组中,最后再进行把它复制回来. 冒泡排序:是稳定排序,适用于排列的数组较小而且基本有序,否则时间复杂度太高. 选择排序:和冒泡排序差不多,差别是冒泡是相邻的比较,最后选出最大的或者最小的

十大经典排序算法小结

排序可以说是套路最多的基本算法了,今天来了兴致,那就总结一下这十大排序算法吧. 冒泡法: 这可以算是知名度最高的算法之一了吧,可以说不会这个算法都不好意思说自己写过代码.冒泡排序是最简单的排序之一了,其大体思想就是通过与相邻元素的比较和交换来把小的数交换到最前面.这个过程类似于水泡向上升一样,因此而得名.不多说了,直接上代码: #include<iostream> #include<algorithm> using namespace std; #define LEN 6 int

C++排序算法小结

近期来闲来无事,整理了一些比较常见的排序算法,都是用C++写的,其中包括:直接插入排序.折半插入排序.冒泡排序.选择排序.快速排序.堆排序.归并排序.希尔排序.基数排序,计数排序和桶排序,总共11种算法,其中时间复杂度为O(n^2)为前4种,中间4中的时间复杂度为O(nlgn),最后3种的时间复杂度为O(n).下面我们分3个栏目来介绍:n^2排序.nlgn排序和线性排序. 注:A为全局变量,为一维int数组 n^2排序 直接插入排序 类似于扑克牌排序的原理,在斗地主的时候,每当摸到一张牌后就插入

排序算法小结(Java)1:冒泡排序

冒泡排序:冒泡排序是排序算法中较简单的排序算法: 它从第一个元素开始重复地走访过要排序的数列,一次比较两个元素,如果a[j]>a[j+1]就把他们交换过来,知道最后一个元素,这样未被排序的元素中最大元素"浮"到数列顶端:接着对未排序元素重复之前操作,数组完成排序. public class BubbleSort { public void sort(int a[]){ int temp = 0; for(int i=a.length-1; i>0; i--){//i为未被排

三种排序算法小结

首先是归并排序,基本思想为分治,合并的技巧比较重要,不是原址排序. 代码如下; int merge(int* x,int left,int mid,int right) { int i,j,k; int L1 = mid-left+2; int L2 = right-mid+1; int* L = new int[L1]; int* R = new int[L2]; memcpy(L,x+left,sizeof(int)*L1); memcpy(R,x+mid+1,sizeof(int)*L2)