zoukankan      html  css  js  c++  java
  • 常见排序算法c++总结

    总结一下常见的排序算法,包括插入排序,冒泡排序,快速排序,

    1.直接插入排序

    整个序列分为有序区和无序区,取第一个元素作为初始有序区,然后第二个开始,依次插入到有序区的合适位置,直到排好序。

    下面是具体代码实现:

    void InsertSort2(vector<int> &num){
        for(int i = 1;i < num.size();++i){
            for(int j = i;j > 0;--j){
                if(num[j] < num[j - 1]){
                    int temp = num[j];
                    num[j] = num[j-1];
                    num[j-1] = temp;
                }
            }
        }
    }

    插入排序的时间复杂度最好的情况是已经是正序的序列,只需比较(n-1)次,时间复杂度为O(n),最坏的情况是倒序的序列,要比较n(n-1)/2次,时间复杂度为O(n^2 ) ,平均的话要比较时间复杂度为O(n^2 )。

    插入排序是一种稳定的排序方法,排序元素比较少的时候很好,大量元素便会效率低下。

    2.冒泡排序

    比较相邻的元素,如果反序则交换,过程也是分为有序区和无序区,初始时有序区为空,所有元素都在无序区,经过第一趟后就能找出最大的元素,然后重复便可。

    冒泡排序感觉非常好理解,第一个for循环是遍历所有元素,第二个for循环是每次遍历元素时都对无序区的相邻两个元素进行一次比较,若反序则交换。

    时间复杂度最坏的情况是反序序列,要比较n(n-1)/2次,时间复杂度为O(n^2 ),最好的情况是正序,只进行(n-1)次比较,不需要移动,时间复杂度为O(n),而平均的时间复杂度为O(n^2 )。

    但是还有更好的方法,如果第一次比较完没有交换即说明已经有序,不应该进行下一次遍历。
    还有已经遍历出部分有序的序列后,那部分也不用进行遍历,即发生交换的地方之后的地方不用遍历。

    void BubbleSort(int arr[], int len){
     int i,temp;
     //记录位置,当前所在位置和最后发生交换的地方
     int current,last = len - 1;
     while(last > 0) {
      for(i = current = 0;i < last;++i){
       if(arr[i] > arr[i+1]){
        temp = arr[i];
        arr[i] = arr[i+1];
        arr[i+1] = temp;
        //记录当前的位置,如果没有发生交换current值即for循环初始化的0
        current = i;
       }
      }
      //若current = 0即已经没有可以交换的元素了,即已经有序了
      last = current;
     }
    }

    冒泡排序也是一种稳定的排序算法,也是元素较少时效率比较高。

    3.快速排序

    快速排序首先选一个轴值(pivot,也有叫基准的),将待排序记录划分成独立的两部分,左侧的元素均小于轴值,右侧的元素均大于或等于轴值,然后对这两部分再重复,直到整个序列有序。过程是和二叉搜索树相似,就是一个递归的过程。

    //快速排序;
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    void Quick_sort(int a[],int left,int right) //快速排序;
    {
        if(left > right)    return;
        int i = left,j = right;
        int base = a[left];     //记录基准数;
        while(i != j)
        {
            while(i < j && a[j] >= base)    //先从基准数的对面开始找;
                j--;
            while(i < j && a[i] <= base)    //再从另一边找;
                i++;
            if(i < j)               //在i和j未相遇时;
                swap(a[i],a[j]);    //交换两个数;
        }
        swap(a[left],a[i]);         //将基准数归位;
        Quick_sort(a,left,i-1);     //处理左区间;
        Quick_sort(a,i+1,right);    //处理右区间;
    }

    这个图不是一般的棒!!来自Wikipedia。
    2016-07-14_Sorting_quicksort_anim.gif

    快速排序时间复杂度的最好情况和平均情况一样为O(nlog2 n),最坏情况下为O(n^2 ),这个看起来比前面两种排序都要好,但是这是不稳定的算法,并且空间复杂度高一点( O(nlog2 n))。而且快速排序适用于元素多的情况。

    未完待续...

  • 相关阅读:
    在这个互联网泡沫时代,施主你有何焦虑?
    对于公司最近一次技术分享的总结
    Windows系统下Redis的安装
    论语
    系统的简单和复杂是由什么决定的?
    Swift之 ? 和 !
    div模拟table,可实现左右高度同增长(html布局)
    动态添加的无缝轮播
    根据数据库名获取表和字段信息(mysql版)
    博客园更新了?
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10326088.html
Copyright © 2011-2022 走看看