排序算法(1)

1.冒泡排序

void bubblesort(int num[],const int len)
{
    if (len <= 1) return;

    bool sign = false;
    int i, j, tmp;

    for ( i = 0; i < len - 1; i++)
    {
        sign = false;
        for ( j = len - 1; j > i; j--)
        {
            if (num[j] < num[j - 1])
            {
                sign = true; //本轮循环存在排序操作
                tmp = num[j - 1];
                num[j - 1] = num[j];
                num[j] = tmp;
            }
        }
        if (!sign) break; //本轮循环排序已经结束
    }
}

最好时间复杂度为O(n),最差和平均时间复杂度均为O(n^2),稳定排序。

2.鸡尾酒排序(可以理解为双向冒泡排序)

void cocktail_sort(int num[], const int len)
{
    if (len <= 1) return;

    int i, left = 0, right = len - 1, temp;

    while (left<right)
    {
        for (i = left; i < right; i++)
        {
            if (num[i]>num[i + 1])
            {
                temp = num[i];
                num[i] = num[i + 1];
                num[i + 1] = temp;
            }
        }
        right--;
        for (i = right; i > left; i--)
        {
            if (num[i - 1] > num[i])
            {
                temp = num[i - 1];
                num[i - 1] = num[i];
                num[i] = temp;
            }
        }
        left++;
    }
}

效果基本与冒泡排序接近,对于大量乱序数据,其效率还是呵呵。

3.直接插入排序

void insertsort(int num[],const int len)
{
    if (len <= 1) return;

    int i, j, temp;

    for ( i = 1; i < len; i++)
    {
        if (num[i] < num[i - 1])
        {
            temp = num[i];
            for (j = i - 1; j >= 0 && num[j] > temp; j--)
            {
                num[j + 1] = num[j];
            }
            num[j + 1] = temp;
        }
    }
}

引用自:http://www.cnblogs.com/heyuquan/p/insert-sort.html中解释

设数组为a[0…n]。

  1. 将原序列分成有序区和无序区。a[0…i-1]为有序区,a[i…n] 为无序区。(i从1开始)
  2. 从无序区中取出第一个元素,即a[i],在有序区序列中从后向前扫描。
  3. 如果有序元素大于a[i],将有序元素后移到下一位置。
  4. 重复步骤3,直到找到小于或者等于a[i]的有序元素,将a[i]插入到该有序元素的下一位置中。
  5. 重复步骤2~4,直到无序区元素为0

时间复杂度:最好O(n),最差、平均都是O(n)。

4.归并算法(采用递归,办法很棒)

//子区间归并函数
void merge(int num[], const int left, const int mid, const int right)
{
    int n1, n2, i, j, k;
    int *L = nullptr, *R = nullptr;

    n1 = mid - left + 1;
    n2 = right - mid;

    L = new int[n1];
    R = new int[n2];

    for ( i = 0; i < n1; i++)
        L[i] = num[left + i];
    for ( i = 0; i < n2; i++)
        R[i] = num[mid + 1 + i];

    i = j = 0; k = left;
    while (i < n1&&j < n2)
    {
        if (L[i] <= R[j])
            num[k++] = L[i++];
        else
            num[k++] = R[j++];
    }

    //左数组或者右数组存在剩余元素
    //将剩余元素合并至原数组末尾处
    for (; i < n1; i++)
        num[k++] = L[i];
    for (; j < n2; j++)
        num[k++] = L[j];

    delete[] L;
    delete[] R;
}

//采用递归的方式,划分子区间进行排序,最后对子区间进行归并
void mergesort(int num[],const int left,const int right)
{
    if (left >= right) 
        return;
    else if (right - left >= 50)
    {
        int mid = (left + right) / 2;
        mergesort(num, left, mid);
        mergesort(num, mid + 1, right);
        merge(num, left, mid, right);
    }
    else
    {
        insertsort(num + left, right - left + 1);
    }
}

此处为归并排序的改进版,即字串的数据较少时,采用直接插入法进行排序。在较大数据量的情况下,提升效果较为明显。

使用该改进方法,归并排序仍然为稳定排序,在处理大数据的时候,若要求为稳定,使用此方法较为不错

原文地址:https://www.cnblogs.com/jason1990/p/4678171.html