JAVA数据结构与算法(三)、排序算法

排序算法

序也称排序算法(Sort Algorithm)排序是将数据,依指定的顺序进行排过程。java

序的分类:redis

1) 部排序:指将须要处理的全部数据都加内部存储器中进行排序。算法

2) 外部排序法:数据量过大,没法所有加载到中,须要借助外部存储进行排序数组

3) 常见的排序算法分类(右图):缓存

l算法的时间复杂度

量一个程(算法)行时种方法

1) 后统计的方
这种方法可 , 是有两个 问题
一是要想对设计的算法的运行性能进行评测 须要 际运 行该程序;
二是所得时间的统计量依赖于计算机的硬件、软件等环境因 , 这种方式,要在同一台计算机的相同状态下运行,才能比较哪一个算法 度更快
 
2) 事前估 算的方
经过分析某个算法的 时间复杂度 来判断哪一个算法更优 .

间频

间频:一个算法花费的时间与算法中语句的执行次数成正比例,哪一个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)函数

例说明-基本案例

1-100全部数字之, 咱们设计两种算法:性能

T(n)=n+1;测试

T(n)=1;优化

举例说明-忽略常数项

 

T(n)=2n+20spa

T(n)=2*n

T(3n+10)

T(3n)

1

22

2

13

3

2

24

4

16

6

5

30

10

25

15

8

36

16

34

24

15

50

30

55

45

30

80

60

100

90

100

220

200

310

300

300

620

600

910

900

结论:

1) 2n+20 2n 随着 n 变大 执行曲线无限接近 , 20 能够忽略
2) 3n+10 3n 随着 n 变大 行曲线无限接近 , 10 以忽略
 

忽略低次项

 

T(n)=2n^2+3n+10

T(2n^2)

T(n^2+5n+20)

T(n^2)

1

15

2

26

1

2

24

8

34

4

5

75

50

70

25

8

162

128

124

64

15

505

450

320

225

30

1900

1800

1070

900

100

20310

20000

10520

10000

 

结论:

1) 2n^2+3n+10 2n^2 随着 n 变大 , 行曲线无限接近 , 能够忽略 3n+10
2) n^2+5n+20 n^2 随着 n 变大 , 执行曲线无限接近 , 能够忽 5n+20
 

时间复杂度

1) 般状况下,算法中的基本操做语句的重复执行次数是问题规模 n 的某个函数,用 T(n) 表示,如有某个辅助函数 f(n) ,使得当 n 趋近于无穷大时, T(n) / f(n) 的极限值为不等于零的常数,则称 f(n) T(n) 的同数量级函数。记做 T(n)= ( f(n) ) ,称O ( f(n) )  为算法的渐进时间复杂度,简称时间复杂度
2) T(n ) 不一样,但时间复杂度可能相同。 如: T(n)= n²+7n+6 T(n)= 3n²+2n+2 它们的 T(n)  不一样,但时间复杂度相同,都为 O(n²)
3) 算时间复杂度的方 法:
 
用常数 1 代替运行时间中的全部加法常数  T(n)=n²+7n+6  => T(n)= n²+7n+1
修改后的运行次数函数中,只保留最高阶项  T(n)= n²+7n+1 => T(n) = n²
去除最高阶项的系 T(n) = => T(n) = n² => O(

常见的时间复杂度

1) 数阶 O(1 )
2) 数阶 O( log 2 n )
3) 线 性阶 O(n )
4) 线 性对数阶 O(n log 2 n )
5) 方阶 O(n^2)
6) 方阶 O(n^3)
7) k 次方阶 O( n^k )
8) 数阶 O(2^n )
常见的算法时间复杂度由小到大依次为: Ο(1) Ο( log 2 n ) Ο( n) Ο( nlog 2 n ) Ο( n 2 ) Ο( n 3 ) Ο( n k ) Ο( 2 n ) ,随 着问题规模 n 的不断增大,上述时间复杂度不断增大,算法的执行效率越
从图中可见,咱们应该尽可 免使用 指数阶的算法
 
 

1)数阶O(1)

论代码执行了多少行,只要是没有循环等复杂结构,那这个代码的时间复杂度就都是O(1)

上述代码在执行的时候,它消耗的时候并不随着某个变量的增加而增加,那么不管这类代码有多长,即便有几万几十万行,均可以用O(1)来表示它的时间复杂度。

2)对数阶O(log2n)

while循环里面,每次都将 i 乘以 2,乘完以后,i 距离 n 就愈来愈近了。假设循环x次以后,i 就大于 2 了,此时这个循环就退出了,也就是说 2 x 次方等于 n,那么 x = log2n就是说当循环 log2n 次之后,这个代码就结束了。所以这个代码的时间复杂度为:O(log2n O(log2n) 的这个2 时间上是根据代码变化的,i = i * 3 ,则是 O(log3n) .

 

3)线性阶O(n)

说明:这段代码,for循环里面的代码会执行n遍,所以它消耗的时间是随着n的变化而变化的,所以这类代码均可以用O(n)来表示它的时间复杂度

4)线性对数阶O(nlogN)

说明:线性对数阶O(nlogN) 其实很是容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN)

5)方阶O(n²)

说明:平方阶O(n²) 就更容易理解了,若是把 O(n) 的代码再嵌套循环一遍,它的时间复杂度就是 O(n²)这段代码其实就是嵌套了2n循环,它的时间复杂度就是 O(n*n),即  O(n²) 果将其中一层循环的n改为m那它的时间复杂度就变成了 O(m*n)

6)方阶O(n³)K次方阶O(n^k)

考上面的O(n²) 去理解就行了,O(n³)至关于三层n循环,其它的相似

算法的时间复杂度

均时间复杂度和最坏时间复杂度

1) 均时间复杂度是指全部可能的输入实例均以等几率出现的状况下,该算法的运行时间
2) 坏状况下的时间复杂度称最坏时间复杂度。通常讨论的时间复杂度均是最坏状况下的时间复杂度。 这样作的缘由是:最坏状况下的时间复杂度是算法在任何输入实例上运行时间的界限,这就保证了算法的运行时间不会比最坏状况更长
3) 平均 时间 复杂度和 坏时间复杂度 否一致,和算法有关 ( 如图 :)

算法的空间复杂度简介

1) 似于时间复杂度的讨论,一个算法的空间复杂度 (Space Complexity) 义为该算法所耗费的存储空间,它也是问题规模 n 的函数
2) 空间复杂度 (Space Complexity) 是对一个算法在运行过程当中临时占用存储空间大小的量度 。有 的算法须要占用的临时工做单元数与解决问题的规模 n 有关,它随着 n 的增大而增大,当 n 较大时,将占用较多的存储单元,例 如快 速排序和归并排序算法就属于这种情
3) 在作算法分析时, 主要讨论的是时间复杂度 。从用户使用体验上看,更看重的程序执行的速度。一些缓存产品 ( redis , memcache ) 和算法 ( 基数排序 ) 本质就是用空间换时间 .
 
 

冒泡排序

冒泡排序(Bubble Sorting)的基本思想是:经过对待排序序列从前向从下标较小的元素开始),依次比较相邻元素的若发现逆序则交换,使大的元素逐渐从移向后部,就象水底下的气泡同样逐渐向上冒。

/**
 * @author Sun.Mr
 * @create 2019-09-20 22:19
 */
public class Bubblesort {


    public static void main(String[] args) {
        int arr[] ={3,-2,9,10,7};

        int temp = 0;//临时变量
        for (int i = 0; i <arr.length ; i++) {
            //若是前面的数比后面的数大,则交换
            for (int j = 0; j <arr.length-1-i ; j++) {
                if (arr[j] > arr[j+1]) {
                    temp=arr[j];
                    arr[j] =arr[j+1];
                    arr[j+1]=temp;
                }
            }
            System.out.println("第"+(i+1)+"趟排序后的数组");
            System.out.println(Arrays.toString(arr));
        }
    }
}

优化:由于排序的过程当中,各元素不断接近本身的位置,若是一趟比较下来没有进行过交换,就说明序列有序,所以要在排序过程当中设置一个标志flag判断元素是否进行过交换。从而减小没必要要的比较

测试8000个数的冒泡排序的时间

排序80000个数,所需时间是9秒

选择排序

择式排序也属于内部排序法,是从欲排序的数据中,按指定的规则选出某一元素,定交换位置后达到排序的目的

选择排序思想:

选择排序(select sorting)也是一种简单的排序方法。它的基本思想是:第一次arr[0]~arr[n-1]中选取最小值,arr[0]交换,第二次arr[1]~arr[n-1]中选取最小值,arr[1]交换,第三次arr[2]~arr[n-1]中选取最小值,arr[2]交换,,第iarr[i-1]~arr[n-1]中选取最小值,arr[i-1]交换,…, n-1arr[n-2]~arr[n-1]中选取最小值,arr[n-2]交换,总共经过n-1次,获得一个按排序码从小到大排列的有序序列

选择排序的思路图解

相关文章
相关标签/搜索