2019-04-14

一: 数据结构和算法

前言:今天内容主要是了解数据结构和算法的一些基础概念,重点找掌握
大O计数法(重点)、排序算法、查找算法。

  • 你需要掌握的技术:
    • Java和Python的简单语法规则
    • Java的面向对象<加分>
    • Java和Python中的一些常见集合

前置学习条件

数据结构的作用?

底层存储数据的方式,数据结构的选取直接决定了数据的CRUD的优缺点。
应对于不同的应用和需求场景。

算法的作用?

算法就是将已知的结构,通过有限的步骤获取到一个或者多个输出结果。
(输入、输出、确定、可行、有穷)

数据结构和算法的关系?

数据结构就是为算法提供服务的,算法是围绕数据结构展开操作的。
不同的数据结构底层存储方式不同、不同的存储方式选择不同的算法完成操作。
单纯想要通过算法解决一个问题是不现实的,算法是在数据结构的基础上建立起来的。

如何评价一个算法是否优秀?

时间复杂度:重点
空间复杂度:
固定空间内存 (代码、常数、变量) 通过集合迭代
变动空间内存 程序随着时间的推延,某个对象(引用类型)变得极为臃肿。

1-1 大O计数法

1:什么是大O计数法
2: 规则:
    * 加法规则
    * 乘法规则
    * 均摊复杂度
    * 常见复杂度分析

1-1-1 : 什么是大O计数法(big notation)

T(n)=O(f(n))

T(n)当前算法的执行时间

n 当前数据的规模大小

f(n) 每行代码执行次数的总和,是一个公式

O 代表的代码的执行时间T(n)和f(n) 成正比的。

大O计数法的推导过程

一行代码的执行过程分为:取值->译码->执行。假设一行代码的执行时间是一个
Unit_Time,虽然cpu的个数不同,执行时间不同,但是我们可以粗略的认为是一致的。
写一些测试用例:

测试用例1:

int num1 = 10;
int num2 = 20;
int totle = num1+num2;
System.out.println(totle);

当前这个程序的执行时间是4Unit_Time。

测试用例2:

int totle = 0;
for(int i = 1;i<=100;i++){
    totle += i;
}
System.out.println(totle);

当前这个程序的执行时间是(2N+2)*Unit_Time。
所有代码的执行时间T(n)和每行代码的执行次数成正比关系。

测试用例3:

System.out.println("打印久久乘法表");
for(int i = 1;i<=9;i++){
    for(int j = 1;j<=i;j++){
       System.out.println(i+"*"+j+"="+(i*j)+"\t"); 
    }
    System.out.println();
}

当前这个程序的执行时间是Unit_Time+nUnit_Time+n^2Unit_Time。

随着数据规模的不断增大,可以忽略常数项和系数。
所以一般情况下我们关注的时间复杂度都是关注循环次数最多的那一段代码即可。

规则

* 加法规则(找到循环次数最多的)
* 乘法规则(多次循环)
* 平均复杂度分析(查找的元素的概率/查找的次数)

常见算法

排序算法

冒泡排序

两两元素进行互相比较,一直比较到最后一个数,那么这样一趟下来,最大的一个数字就在
最后,或者是最小的数字在最后。(看程序编写的思路,如果是前一个元素比后一个元素大,互换位置,
那么就是最大元素在最后,如果是前一个元素比后一个元素小,互换位置,那么最后一个元素就是最小元素)。

持续到第二次再进行两两元素比较,确定第二大或者是第二小的数

持续以上步骤,知道整个数组都排序完成。

一般编写

public static void bubbleSort01(int[] arrs){
    for(int i = 0;iarrs[j+1]){
                int temp = arrs[j];
                arrs[j] = arrs[j+1];
                arrs[j+1] = temp;
            }

            System.out.println("第"+(j+1)+"次");
            System.out.println(Arrays.toString(arrs));//Arrays中的方法 可以将数组中的元素迭代出来
        }
    }
}

减少次数

public static void bubbleSort02(int[] arrs){
    for(int i = 0;iarrs[j+1]){
                int temp = arrs[j];
                arrs[j] = arrs[j+1];
                arrs[j+1] = temp;
            }
            System.out.println("第"+(j+1)+"次");
            System.out.println(Arrays.toString(arrs));//Arrays中的方法 可以将数组中的元素迭代出来
        }
    }
}

减少趟数

public static void bubbleSort03(int[] arrs){
    for(int i = 0;iarrs[j+1]){
                int temp = arrs[j];
                arrs[j] = arrs[j+1];
                arrs[j+1] = temp;
                flag = true;
            }

            System.out.println("第"+(j+1)+"次");
            System.out.println(Arrays.toString(arrs));//Arrays中的方法 可以将数组中的元素迭代出来
        }
        //判定一些flag的值
        if(!flag){
            return;//跳出整个循环 不做了
        }
    }
}

选择

用第一个元素依次和所有元素进行比较,如果存在比当前第一个元素小的值,则记录位置。
整个一次比较过程中,确定了最大或者是最小元素的索引。
总共比较lenght-1次,每一次都会确定一个最小元素

public static void selectSort(int[] arrs){
    // 先对于arrs进行判定
    for(int i = 0;iarrs[j]){
                index = j;
            }
        }

        if(index!=i){
            int temp = arrs[i];
            arrs[i] = arrs[index];
            arrs[index] = temp;
        }

    }

}

查找算法:

** 二分查找法(折半查找)**

保证数组有序的前提下,包含最小索引min(0),最大索引(max)。
min<=max前提下,不断求中间索引(mid)的的值,mid=(min+max)/2
根据每次mid的索引对应的值和要查找的元素进行对比,如果
arrs[mid]>value 在mid的左侧,min不动,max=mid-1
arrs[mid] arrs[mid]=value 证明找到了

min>max 证明没有找到

/**
     * 通过二分查找法 查找元素
     * @param arrs 数组
     * @param value 值
     * @return 索引 如果存在分返回对应的索引 如果不存在 返回-1
     */
public static int binearySearch(int[] arrs,int value){
     int max = arrs.length-1;
     int min = 0;
     int mid ;
 
     while(max>=min){
         //计算中间索引
         mid = (max+min)/2;
         if(arrs[mid]>value){//在左侧
             //移动max
             max = mid-1;
         }else if(arrs[mid]

你可能感兴趣的:(2019-04-14)