数据结构和算法学习
算法与数据结构入门基础
1.思考题
判断一个数是否是2的整数次幂。
比如2 4 8 16 32是的
采用按位与运算N&(n-1)
2.什么是算法?
算法简单来说就是解决问题的步骤。五个特征:
有穷性、确定性、可行性有输入、有输出
设计原则:正确性、可读性、健壮性 bug、高效率与低存储。内存+CPU内存占用最小,CPU占用最小,运算速度最快。
评价算法的两个重要指标:
时间复杂度:运行一个程序所花费的时间。O()
常数性时间复杂度O(1)
即运行一行代码:
线性性O(m)
对数性 nlog(n) 快速排序
平方性
时间复杂度优化标准就是:尽量往低的优化,一般在程序中找for while 递归等就能大概算出时间复杂度。
以上几个性能对比:O(1)>O(n)>O(nlogn)>O(n^2)
空间复杂度:运行程序所需要的内存 OOM,一般就是找数组,容器等
3.什么是数据结构?
数据结构是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。
算法和数据结构有什么联系?往往经典的算法就一定会有一个牛b的数据结构,比如Btree索引,红黑树等。
基础数据结构
3.1 List:
a.数组
元素可以快速的随机访问。
缺点是每个元素必须是连续的,当需要扩容时,就要将已经有数组的数据复制到新的存储空间中。
主要有以下两种
(1)ArrayList:使用最多的数据结构,访问快,但是线程不安全
(2)Vector:线程安全,一般用在高并发的系统中
b.链表:
链表结构如下所示,其链式结构注定了访问不能随机,就像火车一样你不能从火车头一下跳到火车尾而是要一节节车厢的去走。但是插入删除快
LinkedList:不能随机访问
Vector、ArrayList和LinkedList三者对比:
性能上来说ArrayList最好,也使用最多,但当集合内的元素需要频繁插入、删除就可以考虑用LinkedList。Vector是线程同步的。所以性能最差,但是安全性最高一般用于高并发系统。
如果能用数组的时候(元素类型固定,数组长度固定),请尽量使用数组来代替List;
如果没有频繁的删除插入操作,又不用考虑多线程问题,优先选择ArrayList;
如果在多线程条件下使用,考虑Vector;
如果需要频繁地删除插入,LinkedList;
如果不清楚的情况下,就用ArrayList。
3.2 Set:
Set用来去重
Set 在Java里面有3种实现方式
(1)HashSet 就是用来去重的 而且去重后元素的顺序和插入的不一样的
(2)TreeSet 是用来排序的,其底层数据结构为红黑树 元素的顺序和插入的不一样的
(3)LinkedHashSet 维护了一个链表,记录了顺序,可以保持插入和输出后的顺序一致
3.3队列
队列在项目中使用非常广泛主要有以下一些场景:
(1)等待队列
(2)//排队场景 如果一个系统流量高 要做这种排队系统
(3)//Mq消息队列
Java中有很多种队列的实现方式,大部分情况下只需要掌握以下几个:
ArrayBlockingQueue:基于数组的阻塞队列实现,也长度是需要定义的,可以指定先讲先出或者先讲后出,是有界队列,在多线程池中的等待队列就就用了这种。
LinkedBlockingQueue:基于链表的阻塞队列,〈该队列由一个链表构成),
其内部实现采用分离锁(读写分离两个锁),从而实现生产者和消费者操作的完全并行运行,是*队列。
PriorityBlockingQueue:基于优先级的阻塞队列(排队场景比较适合,具体实现看代码例子)
DelayQueue:带有延迟时间的Queue,其中的元素只有当其指定的延迟时间到了,
才能够从队列中获取到该元素。应用场景主要有:缓存超时的数据进行移除、空闲连接的关闭等等。
小结: