zoukankan      html  css  js  c++  java
  • 排序算法(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);
        }
    }

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

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

  • 相关阅读:
    es6小记
    CPU密集型和I/O密集型区别
    Gulp小记
    原生表单的小详解
    div无法触发blur事件解决办法
    HMTL列表详解
    Angular开发小笔记
    Angular组件生命周期钩子
    css小笔记
    HTML格式化标签
  • 原文地址:https://www.cnblogs.com/jason1990/p/4678171.html
Copyright © 2011-2022 走看看