zoukankan      html  css  js  c++  java
  • 算法

    总结

    算法分类

    十种常见排序算法可以分为两大类:

    • 比较类排序冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序 属于比较排序。在排序的最终结果里,元素之间的次序依赖于它们之间的比较。每个数都必须和其他数进行比较,才能确定自己的位置
      • 优势:适用于各种规模的数据,也不在乎数据的分布,都能进行排序。可以说,比较排序适用于一切需要排序的情况
      • 劣势:时间复杂度较高,为O(n2)或者O(nlogn),均高于线性时间O(n)
    • 非比较类排序计数排序、基数排序、桶排序则属于非比较排序。非比较排序是通过确定每个元素之前,应该有多少个元素来排序。针对数组arr,计算arr[i]之前有多少个元素,则唯一确定了arr[i]在排序后数组中的位置
      • 优势:非比较排序时间复杂度低,线性时间O(n)
      • 劣势:但由于非比较排序需要占用空间来确定唯一位置。所以对数据规模和数据分布有一定的要求。

    还有一种分类方法,是看待排序的记录是否全部被放置在内存中(注:本文讨论的都是内排序):

    • 内排序:所有待排序的记录都在内存中
    • 外排序:由于记录太多,不能同时放置在内存中,整个排序过程需要内外存之间多次交换数据才能进行。

    算法复杂度 + 空间复杂度

    图片名词解释:

    • n: 数据规模
    • k: “桶”的个数
    • In-place: 占用常数内存,不占用额外内存
    • Out-place: 占用额外内存
    • 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
    • 不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
    • 时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
    • 空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。 

    虽然同样是O(n2)的算法,但是平均时间来看,排序如下: 冒泡排序>选择排序>插入排序

    稳定性

    冒泡排序:稳定 -- 遇到相同的数组,选择不交换即可。

    选择排序:不稳定 -- 在一趟选择,如果当前元素(5)比一个元素(2)小,而该小的元素(2)又出现在一个和当前元素相等 的元素(5')后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5' 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了2 8 5' 5 9,所以选择排序不是一个稳定的排序算法。

    必看:参考文章

    必看:十大经典排序算法最强总结(含JAVA代码实现)

     

    桶排序(请看这里)

    • 相对于计数排序,桶排序和计数排序的差别就在于处理相同数据的差别上。计数排序假设输入数据都属于一个小区间内的整数,而桶排序则是假设输入是由一个随时过程产生的,区间不确定。
    • 计算某元素应该放在哪个桶里:(num-min)/(max-min)表示这个数在(max-min)所占比重,再乘以桶的个数就得到对应桶的编号
    • 当元素均匀分布时,时间复杂度可以优化到O(n)

    请看文章:https://blog.csdn.net/u013521296/article/details/81625859?utm_source=blogxgwz5

     

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    
    /*
    ①找到待排序的数组A的min和max
    ②桶的数量(A.length)
    ③遍历数组A,把每个元素放到对应的桶中
    ④对每个桶的内部进行排序
    ⑤遍历每个桶
     */
    public class BucketSorting {
        public static void main(String[] args) {
            System.out.println("未排序前的A:");
            int[]A={0,30,0,28,19,30,30,28,1,0,29,10,20,20,10,19,29};
            System.out.println(Arrays.toString(A));
            System.out.println("使用桶排序后的A:");
            System.out.println(Arrays.toString(bucketsort(A)));
        }
    
        private static int[] bucketsort(int[] A) {
            int max=Integer.MIN_VALUE;
            int min=Integer.MAX_VALUE;
            //找最值
            for (int i = 0; i <A.length ; i++) {
                max=Math.max(max,A[i]);
                min=Math.min(min,A[i]);
            }
            //计算桶的数目
            int buckets=A.length;
            //把A中的元素分别放到对应的桶中,用ArrayList来实现桶
            ArrayList<ArrayList<Integer>> bucketArray=new ArrayList<>(buckets);
            for (int i = 0; i <buckets ; i++) {
                bucketArray.add(new ArrayList<Integer>());
    
            }
            //遍历元素,并放到桶里面
            for (int i = 0; i <A.length ; i++) {
                int bucketsNum=getBucket(A[i],buckets,min,max);
                bucketArray.get(bucketsNum).add(A[i]);
    
            }
            //对每个桶内部进行排序
            for(int i = 0; i < bucketArray.size(); i++){
           //每个桶内部,这里选择了快排(比较排序,这点很疑惑。你也可以递归使用桶排序)... Collections.sort()-->Arrays.sort()-->快排 Collections.sort(bucketArray.get(i)); } System.out.println(bucketArray.toString());
    //合并每个桶 int count=0; int[] result=new int[A.length]; for(int i = 0; i < bucketArray.size(); i++){ for (int j=0;j<bucketArray.get(i).size();j++){ result[count]=bucketArray.get(i).get(j); count++; } } return result; } //(num-min)/(max-min)表示这个数在(max-min)所占比重, //再乘以桶的个数就得到对应桶的编号 public static int getBucket(int num,int buckets,int min,int max){ return (int)((num-min)*(buckets-1)/(max-min)); }

     

    基数排序 vs 计数排序 vs 桶排序

    这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:

    基数排序:根据键值的每位数字来分配桶
    计数排序:每个桶只存储单一键值
    桶排序:每个桶存储一定范围的数值

  • 相关阅读:
    ios中,在SearchBar里面搜索内容,可根据内容来查找所需的信息资源,可获得SearchBar中的内容
    TableViewCell,TableView,UITableViewCell
    iOS-多线程 ,整理集锦,多种线程的创建
    从服务器获取的 数值,进行值传递,不同的文件夹之间的调用。
    Principle 安装步骤
    Principle: 做动效,选对软件很重要 --- 转载自简书
    ios 给图片添加水印
    symbol(s) not found for architecture x86_64 之 linker command failed with exit code 1 (use -v to see invocation)解决方案排查
    IOS 本地通知推送消息
    【ios 7】 之后的设置系统的状态栏隐藏的方法分享
  • 原文地址:https://www.cnblogs.com/frankcui/p/11189720.html
Copyright © 2011-2022 走看看