一、数据结构和算法概述
1.1什么是数据结构
一门研究非数值计算的程序设计问题中的操作对象,以及它们之间的关系和操作等相关问题的学科。
数据结构就是把诗句元素按照一定的关系组织起来的集合,用来组织和存储数据。
1.2数据结构的分类
数据结构可以分为逻辑结构和物理结构两大类
-
逻辑结构的分类(按照不同元素之间的关系区别)
- 集合结构:集合结构中的数据元组属于同一个集合,其他无任何关系
- 线性结构:元素之间的关系为一对一
- 树形结构:一对多
- 图形结构:多对多
-
物理(存储)结构的分类(逻辑结构在计算机中真正的表示方式(又称为映像))。
-
顺序存储结构(连续的内存单元,元素都有自己的索引)
访问简单,增删麻烦
-
链式存储结构(内存单元不确定,元素之间靠指针连接)
增删简单,访问麻烦
-
1.3算法
算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。
根据一定的条件,对一些数据进行计算,得到需要的结果。
优秀的算法有两个追求:
- 花最少的时间完成需求;
- 占用最少的内存空间完成需求 ;
1.4算法初识
计算n的阶乘;
package com.zebra.chapter01;
//计算10的阶乘
public class Demo01 {
//解法一:for循环
//解法二:递归
public static long solution1(int n){
long result = 1;
for (int i = 0; i < n; i++) {
result*=(i+1);
}
return result;
}
public static long solution2(int n){
if(n==1)
return 1;
else
return n*solution1(n-1);//有long型整个表达式自动转换成long型
}
public static void main(String[] args) {
int n = 20 ;
System.out.println(solution1(n));
System.out.println(solution2(n));
}
}
一、算法分析
算法研究的最终目的是如何花最少的时间,占用最小的内存完成相同需求。为此需要对算法进行时间复杂度分析和空间复杂度分析
1.1时间复杂度
-
事后分析估算方法
对事先写好的代码计时,确定算法的效率
缺陷:
- 必须依据已经写好的程序,时间和精力耗费大
- 会受到测试环境的影响
-
事前分析估算方法
在程序编写前,依据统计方法估算,高级语言编写的程序在计算机上消耗的时间取决于下列因素:
- 算法采用的策略和方案
- 编译产生的代码质量(由编译器决定)
- 问题输入规模
- 机器执行的指令速度(计算机决定)
由此可见,抛开硬件和软件有关因素,一个程序的运行时间依赖于算法的好坏和问题的输入规模。如果算法固定,那么该算法的执行时间就之和输入的规模有关系了
public static void main(String[] args) { int i; int n = 100; int sum = 0; //算法1 for (i = 0; i < n; i++) { sum += (i + 1); //执行n次 } //算法2 sum = 0; sum = n * (n + 1) / 2;//执行一次 }
算法的时间复杂度分析只关心核心代码执行的次数与输入规模之间的关系数量级,算法1的时间复杂度为O(n),算法2的时间复杂度为O(1),只需要关心最高次幂即可。对数阶可以忽略对数的底数。
1.2空间复杂度分析
1.2.1 java中内存占用
- 基本数据类型内存占用
数据类型 | 内存占用字节数 |
---|---|
byte | 1 |
short | 2 |
int | 4 |
long | 8 |
float | 4 |
double | 8 |
boolean | 1 |
char | 2 |
- 计算机访问内存的方式都是一次一个字节
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IWcXGUF8-1645406052289)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20210727100057642.png)]
-
一个引用需要八个字节表示
-
new一个新对象,除对象本身占用的内存外,对象自身也有内存开销,每个对象字节开销量是16字节,用来保存对象头信息。
-
一般内存的占用,如果不够八字节,会被自动填充为8字节
public class A{ public int a = 1; } 此时new一个A对象,由于一个int占四字节,所以会被填充为8字节,整个对象加上自身内存一共占用24字节内存
-
java数组是限定对象,他们会因为要记录自身长度所以需要额外的内存,一个原始类型的数组一般需要24字节内存(16字节自身+4字节保存长度+4字节填充字节)
1.2.1 算法的空间复杂度
算法的空间复杂度计算公式为:S(n) = O(f(n)),n为输入规模,f(n)为语句关于n所占存储空间的函数
案例:反转数组元素
public static int[] reverse1(int[] arr) {
int tem;//四字节
for (int start = 0, end = arr.length; start < end; start++, end--) {
tem = arr[start];
arr[start] = arr[end];
arr[end] = tem;
}
return arr;
}
public static int[] reverse2(int[] arr) {
int[] arr1 = new int[arr.length];//申请4*n+24个字节
for (int i = 0; i < arr.length; i++) {
arr1[i] = arr[arr.length - i];
}
return arr1;
}
算法一的空间复杂度为O(1),算法二的空间复杂度为O(n)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8x5IuLnS-1645406052290)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20210802082110944.png)]
length - i];
}
return arr1;
}
算法一的空间复杂度为O(1),算法二的空间复杂度为O(n)
![在这里插入图片描述](https://img-blog.csdnimg.cn/eff2197b60eb4571ad28e12c30da8715.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAemVicmEyNTAw,size_20,color_FFFFFF,t_70,g_se,x_16)