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

     

    参考:

    常见排序算法C++总结

    各种排序算法的总结

    冒泡、插入、选择等容易理解的排序思路

    总结: Sort 排序算法

    c++ 插入排序算法

     

    1、插入排序      稳定

    时间复杂度O(n×n),空间复杂度O(1)。

    两根指针,分别指向有序区最后一个元素和无序区第一个元素。

    代码:

    void insertSort(vector<int> &num)
    {
        int size=num.size();
        for (int i=1;i<size;i++)
        {
            int temp=num[i]; //待排序第一个元素;
            int j=i-1;  //已排序元素最后一个索引;
            while(j>=0&&temp<num[j])
            {
                //从后向前逐个比较已经排序过数组,如果比它小,排序数组元素后移一位;
                //其实说白了就是数组逐个后移动一位,为找到合适的位置时候便于Key的插入;
                num[j+1]=num[j];
                j--;
            }
            num[j+1]=temp;
        }
    }

     

    2、冒泡排序      稳定 

    时间复杂度O(n×n),空间复杂度O(1)。

    每次比较如果发现较小的元素在后面,就交换两个相邻的元素。 

    代码:

    /*
    冒泡法循环终止条件说明(优化);
    第一次找到n个元素中最大的放在最后;
    第二次找到n-1个元素中最大的放在倒数第二位;
    ……
    最后一次找到2个元素中最大的放在第二位;
    即是说,外层循环一共进行了n-1次就已经排好序了;
    */
    
    void BubbleSort(vector<int> &nums)
    {
        int size=nums.size();
        for (int i=0;i<size-1;i++)//i<size也可以;
        {
            for (int j=0;j<size-i-1;j++)//注意循环终止条件,j+1不应超出范围;
            {
                if (nums[j]>nums[j+1])
                {
                    swap(nums[j],nums[j+1]);
                }
            }
        }
    }
    
    //冒泡法改进(如果一趟扫描过程无交换,则排序可结束);
    
    void BubbleSortBetter(vector<int> &nums)
    {
        int size=nums.size();
        int current=0,last=size-1;//定义并初始化当前发生交换位置与最后一次发生交换的位置;
    
        while (last>0)//说明上次扫描有交换;
        {
            current=0;
            for (int i=0;i<last;i++)//last 之后的已排好,不再考虑;
            {
                if (nums[i]>nums[i+1])
                {
                    swap(nums[i],nums[i+1]);
                    //记录交换位置,交换一次更新一次;
                    current=i;
                }
            }
            //若for循环中无交换,则current为0,last为0,循环结束;
            last=current;
        }
    }

    另一种形式的代码:

    /*
    说明;
    第一次找到n个元素中最小的放在最前;
    第二次找到n-1个元素中最小的放在第二位;
    ……
    最后一次找到2个元素中最小的放在倒数第二位;
    即是说,外层循环一共进行了n-1次就已经排好序了;
    */
    void exchangeSort(vector<int> &nums)
    {
        int size=nums.size();
        for (int i=0;i<size-1;i++)
        {
            for (int j=i+1;j<size;j++)
            {
                if (nums[i]>nums[j])
                {
                    swap(nums[i],nums[j]);
                }
            }
        }
    }

     

    3、选择排序       不稳定

    时间复杂度O(n×n),空间复杂度O(1)。

    改进冒泡法,改进之处为:先并不急于调换位置,先从A[0]开始逐个检查,看哪个数最小就记下该数所在的位置P,等一趟扫描完毕,再把A[P]和A[0]对调,这时A[0]到A[n]中最小的数据就换到了最前面的位置。  

     

    冒泡与选择的区别可参考:

    选择排序算法与冒泡排序算法有何异同

    冒泡排序和选择排序

    代码:

    void selectSort(vector<int> &nums)
    {
        int size=nums.size();
        for (int i=0;i<size-1;i++)
        {
            int temp=i;
            for (int j=i+1;j<size;j++)
            {
                if (nums[temp]>nums[j])  //寻找每趟扫描的最小值索引;
                {
                    temp=j;
                }
            }
            if (temp!=i)//若最小值不在i位置,交换最小值与i位置元素;
            {
                swap(nums[i],nums[temp]);
            }
        }
    }

     

    4、快排序          不稳定 

    时间复杂度O(nlogn),空间复杂度O(1)。

    挖坑填数+分治法。(递归)

    选定基准,将大于基准的放到右边,小于基准的放到左边。每次处理完成后,就确定了该基准在数组中的位置。

    参考:快速排序

     

    5、归并排序       稳定

    时间复杂度O(nlogn),空间复杂度O(n)。

    分为两个过程:划分数组,合并数组。可以简单理解为将数组从中间一分为二不停拆分,直到子数组只有单个元素。然后每两个子数组进行排序合并,然后再两两数组进行排序合并……重复该过程直到所有数组合并在一起。

    参考:归并排序

     

     

     

  • 相关阅读:
    (转)多线程同步event
    初始化列表中成员列出的顺序和它们在类中声明的顺序相同
    确定基类有虚析构函数
    (转)list::splice()函数详解
    MANIFEST.MF文件的格式
    NIO入门了解Buffer
    Failed to load class "org.slf4j.impl.StaticLoggerB
    线程挂起自己,让出CPU
    database如何管理超过4GB的文件
    线程同步(C# 编程指南)
  • 原文地址:https://www.cnblogs.com/Tang-tangt/p/8849629.html
Copyright © 2011-2022 走看看