• 排序(四)交换排序


    1.冒泡排序(时间复杂度为 O(N2))

    原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,

    这样一趟过去后,最大或最小的数字被交换到了最后一位;重复此动作直到排好序为止;

    先来cv一个动图看看效果:

    void BubbleSort(vector<int>& Vector)
    {
        for (int i = 0; i < Vector.size(); ++i)
        {
            for (int j = 0; j < Vector.size() - i - 1; ++j)
            {
                if (Vector[j] > Vector[j + 1])
                    swap(Vector[j], Vector[j + 1]);
            }
        }
    }
    
    /*优化*/ void OptimizeBubbleSort(vector<int>& Vector) { int index = Vector.size() - 1; bool sign = true; while (index && sign) { int tmp = -1; for (int i = 0; i < index; ++i) { if (Vector[i] > Vector[i + 1]) { swap(Vector[i], Vector[i + 1]); tmp = i; } } tmp > 0 ? index = tmp : sign = false; } }

    这里奉上一篇关于冒泡排序的博文(超赞): http://blog.csdn.net/lemon_tree12138/article/details/50591859

    2.快速排序

    快速排序也是一种采用分治法解决问题的一个典型应用。在很多编程语言中,对数组,列表进行的非稳定排序在内部实现中都使用的是快速排序。

    借鉴前辈们的动图看下效果先:

    快速排序的基本思想如下:

    1. 对数组进行随机化。
    2. 每次从数列中取出最后一个数作为参照;
    3. 将比这个数大或者等于的数放到它的右边,小于它的数放到它的左边。
    4. 再对左右区间重复第三步,直到各区间只有一个数。

    举个栗子:

    /*方式一:见上图 ↑↑↑↑↑↑*/
    int
    _QuickSort(vector<int>& Vector, int left, int right) { int middle = left + (right - left) / 2; /*优化一:三数取中*/ int MaxNumber = Max(Vector[left],Max(Vector[middle], Vector[right])); int MinNumber = Min(Vector[left],Min(Vector[middle], Vector[right])); if (Vector[left] > MinNumber && Vector[left] < MaxNumber) swap(Vector[left], Vector[right]); else if (Vector[middle] > MinNumber && Vector[middle] < MaxNumber) swap(Vector[middle],Vector[right]); int begin = left, end = right - 1; int key = Vector[right]; while (begin < end) { while (begin < end && Vector[begin] < key) ++begin; while (begin < end && Vector[end] >= key) --end; swap(Vector[begin], Vector[end]); } if (Vector[begin] > key) { swap(Vector[begin], Vector[right]); return begin; } else { return right; } } /*方式二;挖坑法*/ int _QuickSort(vector<int>& Vector, int left, int right) { int begin = left, end = right; int key = Vector[right]; while (begin < end) { while (begin < end && Vector[begin] < key) ++begin; Vector[end] = Vector[begin]; while (begin < end &&Vector[end] >= key) --end; Vector[begin] = Vector[end]; } Vector[begin] = key; return begin; } /*方式三:前后指针法*/ int _QuickSort(vector<int>& Vector, int left, int right) { int begin = left, small = left - 1, end = right; int key = Vector[right]; while (begin < end) { if (Vector[begin] < key) { ++small; swap(Vector[small], Vector[begin]); } ++begin; } swap(Vector[++small ], Vector[end]); return small; }
    void QuickSort(vector<int>& Vector, int left, int right)
        {
            if (right - left > 13)    //优化二:当区间小到一定程度时,使用插入排序
            {
                int middle = _QuickSort(Vector, left, right);
                QuickSort(Vector, left, middle - 1);
                QuickSort(Vector, middle+1, right);
            }
            else
            {
                //插入排序
                InsertSort(Vector, left, right);
            }
        }
    
    
    /*插入排序*/
    void InsertSort(vector<int>& Vector, int left, int right)
        {
            for (int i = left; i<right; ++i)
            {
                int end = i;
                int key = Vector[end + 1];
                while (end >= left && Vector[end] > key)
                {
                    Vector[end + 1] = Vector[end];
                    --end;
                }
                Vector[end + 1] = key;
            }
        }

    算法分析:

    1. 在最好的情况下,快速排序只需要大约nlgn次比较操作,在最坏的情况下需要大约1/2 n次比较操作。
    2. 在最好的情况下,每次的划分都会恰好从中间将序列划分开来,那么只需要lgn次划分即可划分完成,每一次划分都需要比较N次。
    3. 在最坏的情况下,即序列已经排好序的情况下,每次划分都恰好把数组划分成了0,n两部分,那么需要n次划分,但是比较的次数则变成了n, n-1, n-2,….1, 所以整个比较次数约 为 nnndf n(n-1)/2~n2/2.
    4. 平均情况下,快速排序需要大约1.39NlgN次比较,这比合并排序多了39%的比较,但是由于涉及了较少的数据交换和移动操作,他要比合并排序更快。
    5. 快速排序是非稳定性排序。
  • 相关阅读:
    hibernate和mybatis区别
    Spring事务的传播行为和隔离级别
    数组拷贝
    spring mvc 一次请求 两次查询
    手游性能之渲染分析3
    Android pm 命令详解
    Android am命令使用
    Android dumpsys命令详细使用
    java处理高并发高负载类网站的优化方法
    关于ArrayList的5道面试题
  • 原文地址:https://www.cnblogs.com/shihaochangeworld/p/5572813.html
Copyright © 2020-2023  润新知