轻松学算法

轻松学算法

1数组、集合、和散列表

①.数组(Array):定长有序下标由0开始。

二维数组:数组里面包含另一个数组(int [] [] num =new int [3] [3];)

②.集合(动态数组):可变长度的数组。

集合的实现(ArrayList):基于数组实现,当往里面添加元素的时候会判断长度够不够,不够的话会扩容,就是创建一个新的数组然后将老数组里面的元素复制过来,长度够的话直接添加。

集合的系统开销:

1、数组总是比实际使用的长度长,存在空间浪费。

2、当数组不够长时需要创建一个更长的数组,同时复制数据,这个操作消耗性能。

3、集合越来越长时效率会逐渐变低,但是散列表不会。

③.散列表(哈希表):散列表是一种空间换时间的存储结构。

经常适用于缓存,快速查找,特点无序,键值对。

哈希碰撞:通过不同的key可能访问到同一个地址。

如何解决哈希碰撞

开放地址法:存值的时候发现键位已经有值了,所以在存值的时候会先探测这里有没有值,有的话比如往后移一个地址,如果超过最大程度,则对总长度取余,这里移动的地址是产生冲突的增列序量。

再哈希法:发生冲突后,使用关键字的其他部分继续计算地址,如果还是有冲突则继续使用其他部分计算地址,缺点是增加了时间。

链地址法(java使用):落在同一个地址上的值使用链表储存。

建立一个公共溢出区:建立一个公共溢出区来存储有冲突的值。

链表:可以简单理解为一条链子,每个元素都会有一个指向下一个元素的指针。

如果键值是String,在java中都会有一个方法hashCode将其转化为整型,如果是负数的话可以直接使用绝对值解决。

键值一样的散列表为Set,不同的为Map.

散列表的性能分析:

在没有碰撞的情况下是O(1)的时间复杂度,但是如果要处理碰撞的话,就会变得复杂,比如链表方式所以时间复杂度变为O(L),其中L为链表的长度,因为可能被分配的地址越大产生碰撞的可能性就越小,那么增加散列表的性能的方式就是扩容——既然说到扩容就有一个扩容因子,在java中一般为0.75,意思就是使用到了百分之75的时候就开始扩容一般扩容的长度为之前的两倍。

 

2栈、队列、和链表

①.栈:先进后出(后进先出)又叫堆栈,是一种只能在一端进行插入和删除的线性数据结构。

一般来说栈主要有两个操作:一个是进栈(PUSH)也叫入栈、压栈;另一个是出栈(POP)或者叫退栈。

栈经常适用于,逆序输出、语法检查(比如括号)、数制转换。

②.队列:先进先出,和栈一样由一端连续的储存空间组成

③.链表:之前说过链表,链表分为单向链表和双向链表,一般说的是单向链表。双向链表除了储存元素数据本身外,还额外储存两个指针,分别指向上一个节点和下一个节点的位置。每个节点包含两个部分,数据(data)和指针(next)。

链表的优势:不需要提前设置长度,可以随意添加元素,存储空间不总是连续的,可以更好的使用储存空间,还能更好的对内存空间进行管理。

 

3排序算法

①算法基础

1.时间复杂度:算法的时间复杂度是一个函数,一般用一个O表示。

2.空间复杂度:算法的空间复杂度和时间复杂度差不多,一般也用O表示。表示在运行过程中所消耗的临时空间的一个度量。

3.稳定性:在排序算法中,存在相等的元素,排序之后这些元素的相对次序保持不变我们称这个算法是稳定的。

②排序

桶排序:将数据作为下标,建一个跟数据量一样大小的数组(桶),每到一个下标时就把值加一,最终倒序输出数组的下标就可以实现排序。

优点是速度快,缺点是空间利用率低。适合数据分布比较均匀,或者数据跨度不大的排序。

冒泡排序:重复的访问数据,一次对比两个如果顺序不对则进行交换,并一直重复这样的过程直到没有需要交换的数据为止。

快速排序:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据比另一部分的所有数据要小,用这种方法对这两部分数据分别进行快速排序。

插入排序:插入排序分两种,一种是直接插入排序,一种是二分插入排序。

posted on 2021-04-06 10:04  Rukewa  阅读(87)  评论(0)    收藏  举报

导航