时间复杂度和两种基础排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sdr_zd/article/details/79388656

一.认识时间复杂度

1.常数时间的操作:

一个操作如果和数据量没有关系,每次都是固定时间内完成的操作,叫做常数操作。

2.时间复杂度:

它是常数操作数量的指标,常用O表示。

计算方法:

在常数操作数量的表达式中,只要高阶项,不要低阶项,也不要系数,剩下的部分如果记为f(N),你们时间复杂度为f(N)*O(1),即O(f(N));
评价一个算法流程的好坏,最先看的指标是时间复杂度,然后分析不同数据样本下的实际运行时间,也就是常数项时间。

e.g1.

两层for循环,第一层循环对常数操作N次,第二层循环对常数操作M次,常数操作量为O(N*M),时间复杂度为O(N*M),因为M和N都是未知数,是要在实际情况下才可以确定的数值所以不能化简。

e.g2.

对常数第一次进行操作N次,第二层进行N-1次操作,第三次进行N-2次操作…第N次进行一次操作,则常熟操作量为:O((N^2 + N)/2),遵循计算方法,取高阶不取低阶并且忽略系数的原则,时间复杂度为O(N^2)。

e.g3

如下有三种算法解决了同一个问题其时间复杂度分别为:

O(M*N)
O(M*logN)
O(M*logM)+O(N+M)

判断一个算法流程的好坏,第一步先从时间复杂度的角度看,由于N一定比logN大,第一种则是最差的算法;然而第二种和第三种算法的时间复杂度无法判断,只有在明确了M和N谁大的情况下才能够判断。如果M较大,则第二种更优,如果N较大则第三种更好,时间复杂度O(f(N))可以直接化简成一阶的表达式O(N+M)。

3.额外空间复杂度:

需要额外申请空间的大小的抽象,比如一个题目,给定了一个数组,设计的流程中又多定义了几个变量,那么额外空间复杂度就是O(1);如果申请了一个与原数组大小相同的数组,那么它的额外空间复杂度就是O(N);如果申请了一个是原数组大小一半的数组,那么它的额外空间复杂度也是O(N),因为忽略系数。

二.两种基础排序算法

前提:给定一个无序数组0~N-1进行排序。

1.冒泡排序

进行多轮比较,每轮比较都是从第一个位置开始,将相邻的两个数进行比较,小的放左边大的放右边,每轮比较的结果都是将最大的数放在当前比较的数组的最后的位置,到下轮比较的时候就不需要再比较那个最大的数,每轮比较都是在找前面还无序的数组中的最大的数,直到最小的数位置也确定了比较结束。

/*
 * 冒泡排序
 * 时间复杂度:O(N^2),额外空间复杂度:O(1)
 */
public static void sort(int[] arr) {
        if(arr == null || arr.length < 2)
            return;

        //每轮比较结束后数组长度由0~end缩短至0~end-1
        for(int end = arr.length-1;end > 0;end--) {
            for(int i = 0;i < end;i++) {
                if(arr[i] > arr[i+1]) {
                    swap(arr, i, i+1);
                }
            }
        }
    }

    public static void swap(int[] arr, int a, int b) {
        int tmp = arr[a];
        arr[a] = arr[b];
        arr[b] = tmp;
    }

2.选择排序

冒泡排序每轮是寻找最大的数,选择排序则是每轮寻找最小的数,但是每轮比较只进行一次交换。最初指定第一个位置上的数是最小的数,则取第一个位置上的数的下标记为最小数的下标minIndex,在遍历这个数组的时候,只要发现比minIndex小的,就将这个数的下标赋给minIndex,在遍历完这个数组之后将最小的数和第一个位置上的数进行交换,下一次比较的时候就将最小的minIndex设为后面无序数组部分的第一个位置,再选出最小的数。。。以此类推比较多轮直到找到最大的数。

/*
 * 选择排序
 * 时间复杂度:O(N^2),额外空间复杂度:O(1)
 */
public static void sort(int[] arr) {
        if(arr == null || arr.length < 2)
            return;

        //每轮比较结束后数组长度由i~length-1缩短至i+1~length-1
        for(int i = 0;i < arr.length;i++) {
            int minIndex = i;
            for(int j = i+1;j < arr.length;j++) {
                minIndex = arr[j] < arr[i] ? j : minIndex;
            }
            swap(arr, i, minIndex);
        }
    }

    public static void swap(int[] arr, int a, int b) {
        int tmp = arr[a];
        arr[a] = arr[b];
        arr[b] = tmp;
    }

猜你喜欢

转载自blog.csdn.net/sdr_zd/article/details/79388656
今日推荐