Java数据结构和算法介绍(一)

数据结构和算法介绍

重要性

  1. 算法是程序的灵魂,优秀的程序可以再海量数据计算时,依然保持高效计算。
  2. 一般来讲程序会使用了内存计算框架(比如Spark)和缓存技术(比如redis等)来优化程序,再深入的思考一下,这些计算框架和缓存技术,它的核心功能是哪个部分呢?
  3. 程序员的面试门槛越来越高,很多一线IT公司(大厂),都会有数据结构和算法面试题。

两者之间的关系

  1. 数据结构是一门研究组织数据方式的学科,有了编程语言也就有了数据结构,学好数据结构可以编写出更加漂亮,更加有效率的代码。
  2. 程序 = 数据结构 + 算法
  3. 数据结构是算法的基础,换言之,想要学好算法,需要把数据结构学到位。
  4. 学习好数据结构就要多多考虑如何将生活中遇到的问题,用程序去实现解决。

数据结构

数据的逻辑结构

集合:同一集合之间的元素存在关系,集合之外的数据之间是没有任何关系的。
线性结构:元素之间存在一对一的关系。
树形结构:元素之间存在一对多的关系。
图形结构:元素之间存在多对多的关系。

按物理结构分类

顺序结构

在内存中开辟出一组地址连续的存储单元,用于存储数据元素。优点:节省空间因为不用额外存储元素间的逻辑关系。查看数据元素快因为每个存储单元对应一个序号,每个序号存储一个数据元素。通过序号可以快速的查找到数据。缺点:插入、删除数据慢因为每次执行此类操作都需要移动元素

链式结构

在内存中开辟出一组任意地址的存储单元(地址可以连续,也可以不连续),用于存储数据。缺点:占用空间大因为除了存储数据外需要额外存储和该元素有逻辑关系的元素所对应的地址。查看数据慢,因为需要从头依次查找,链式存储的地址值可能是不连续的,需要通过上一个数据查找下一个数据的存储地址。优点:插入、删除数据速度快,因为不需要移动元素,只要改变数据中存储的相邻元素的地址值就可以实现。

索引结构

将数据和数据间的关系进行分别存储。存放数据间逻辑关系的区域称为索引区域。优点:提高查询数据的速度,我们可以通过索引区域快速查找到其对应数据的物理地址。缺点:需要额外维护索引区域,增加内存消耗。

哈希存储

哈希存储(散列存储)是存放在一块地址连续的存储区域的。元素的存储位置是将数据的关键值通过哈希算法计算得到的。优点:查询速度快,因为数据的地址值是通过数据本身来决定的,知道地址就可以节省数据查找。缺点:数据过多时,可能会产生哈希值冲突。

按照逻辑结构分类

线性结构

  1. 线性结构作为最常用的数据结构,其特点是数据元素之间存在一对一的线性关系。
  2. 线性结构有两种不同的存储结构,即顺序存储结构(数组)和链式存储结构(链表)。顺序存储的线性表称为顺序表,顺序表中的存储元素是连续的。
  3. 链表存储的线性表称为链表,链表中的存储元素不一定是连续的,元素节点中存放数据元素以及相邻元素的地址信息。
  4. 线性结构常见的有:数组、队列、链表和栈。

非线性结构

非线性结构包括:二维数组、多维数组、广义表、树结构、图结构。

算法

介绍

在Java中,算法通常都是由类的方法来实现的。前面的数据结构,比如链表为啥插入、删除快,而查找慢,平衡的二叉树插入、删除、查找都快,这都是实现这些数据结构的算法所造成的。后面我们讲的各种排序实现也是算法范畴的重要领域。

算法的五大特征

①、有穷性(Finiteness)
算法的有穷性是指算法必须能在执行有限个步骤之后终止;
②、确切性(Definiteness)
算法的每一步骤必须有确切的定义;
③、输入项(Input)
一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定出了初始条件;
④、输出项(Output)
一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的;
⑤、可行性(Effectiveness)
算法中执行的任何计算步骤都是可以被分解为基本的可执行的操作步,即每个计算步都可以在有限时间内完成(也称之为有效性)。

算法的设计原则

①、正确性:首先,算法应当满足以特定的“规则说明”方式给出的需求。其次,对算法是否“正确”的理解可以有以下四个层次:
一、程序语法错误。
二、程序对于几组输入数据能够得出满足需要的结果。
三、程序对于精心选择的、典型、苛刻切带有刁难性的几组输入数据能够得出满足要求的结果。
四、程序对于一切合法的输入数据都能得到满足要求的结果。
PS:通常以第 三 层意义的正确性作为衡量一个算法是否合格的标准。
②、可读性:算法为了人的阅读与交流,其次才是计算机执行。因此算法应该易于人的理解;另一方面,晦涩难懂的程序易于隐藏较多的错误而难以调试。
③、健壮性:当输入的数据非法时,算法应当恰当的做出反应或进行相应处理,而不是产生莫名其妙的输出结果。并且,处理出错的方法不应是中断程序执行,而是应当返回一个表示错误或错误性质的值,以便在更高的抽象层次上进行处理。
④、高效率与低存储量需求:通常算法效率值得是算法执行时间;存储量是指算法执行过程中所需要的最大存储空间,两者都与问题的规模有关。

前面三点 正确性,可读性和健壮性相信都好理解。

对于第四点算法的执行效率和存储量,我们知道比较算法的时候,可能会说“A算法比B算法快两倍”之类的话,但实际上这种说法没有任何意义。因为当数据项个数发生变化时,A算法和B算法的效率比例也会发生变化,比如数据项增加了50%,可能A算法比B算法快三倍,但是如果数据项减少了50%,可能A算法和B算法速度一样。所以描述算法的速度必须要和数据项的个数联系起来。也就是“大O”表示法,它是一种算法复杂度的相对表示方式,这里我简单介绍一下,后面会根据具体的算法来描述。

相对(relative):你只能比较相同的事物。你不能把一个做算数乘法的算法和排序整数列表的算法进行比较。但是,比较2个算法所做的算术操作(一个做乘法,一个做加法)将会告诉你一些有意义的东西;

表示(representation):大O(用它最简单的形式)把算法间的比较简化为了一个单一变量。这个变量的选择基于观察或假设。例如,排序算法之间的对比通常是基于比较操作(比较2个结点来决定这2个结点的相对顺序)。这里面就假设了比较操作的计算开销很大。但是,如果比较操作的计算开销不大,而交换操作的计算开销很大,又会怎么样呢?这就改变了先前的比较方式;

复杂度(complexity):如果排序10,000个元素花费了我1秒,那么排序1百万个元素会花多少时间?在这个例子里,复杂度就是相对其他东西的度量结果。

然后我们再说说算法的存储量,包括:
程序本身所占空间;
输入数据所占空间;
辅助变量所占空间;
一个算法的效率越高越好,而存储量是越低越好。

算法的分类

算法可以宏泛的分为三类:
一,有限的,确定性算法 这类算法在有限的一段时间内终止。他们可能要花很长时间来执行指定的任务,但仍将在一定的时间内终止。这类算法得出的结果常取决于输入值。
二,有限的,非确定算法 这类算法在有限的时间内终止。然而,对于一个(或一些)给定的数值,算法的结果并不是唯一的或确定的。
三,无限的算法 是那些由于没有定义终止定义条件,或定义的条件无法由输入的数据满足而不终止运行的算法。通常,无限算法的产生是由于未能确定的定义终止条件。

Java常用见的算法

①、排序
排序就是对一组数据按照一定的顺序(从大到小或者从小到大)进行排序;
常见排序如下:
简单排序:冒泡排序、选择排序、插入排序;
高级排序:快速排序、希尔排序、归并排序、基数排序、鸡尾酒排序等等;
②、递归
递归是一种直接或者间接调用自身的一种算法,递归的目的是简化程序设计使程序更加易读;
③、查找
在一些(有序的/无序的)数据元素中,通过一定的方法找出与给定关键字相同的数据元素就叫做查找;
④、统计
指对有关数据的搜集、整理、计算、分析、解释、表述等的活动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值