算法:对数据进行的处理。
三个作用:现实世界数据的存储,提高处理数据效率的工具,现实世界的建模。
数据结构包括:数组、有序数组、栈、队列、链表、二叉树、红-黑树、2-3-4树、哈希表、堆、图等。
算法对数据的基本操作:插入、寻找、删除。
数据库(database):相同格式的数据(即记录)的集合。
记录(record):数据库中的一个数据,模拟现实世界的一个实体。
字段(field):记录里的一个属性,模拟现实世界一个实体的某一特征。
关键字(keyword):能够被用于查找某一特定记录的字段。
Java中数组是对象,通过new操作符创建。
优点:知道下标查找速度快,无序数组插入快,有序数组查找快。
缺点:无序数组查找慢,有序数组插入慢,两者删除都慢。并且一旦创建数组,大小固定。
大O表示法(O,order of,大约):表示算法处理数据的效率(时间复杂度)
O(1)优秀,O(logN)良好,O(N)一般,O(N²)较差
线性查找:从前到后依次查找。
二分查找:将有序数据分成两部分,判断位于哪一部分,再均分判断,直至找到特定数据或无法继续均分。
对数组和有序数组操作的效率:
查找 | 插入 | 删除 | |
数组 | O(N) | O(1) | O(N) |
有序数组 | O(logN) | O(N) | O(N) |
log₂N ≈ log10 N * 3.322
冒泡排序:从左到右(或从右到左)依次两两比较并交换,以将最大的(或最小的)移动到一端,重复直至完全有序。
例:2 4 7 5 8 3 6 1 →2 4 5 7 3 6 1 8
一边是完全有序的。
选择排序:只进行比较,直到选出最大(或最小)的数据项,才与一端数据项交换。
例:2 4 7 5 8 3 6 1→2 4 7 5 1 3 6 8
一边是完全有序的。
插入排序:保持一边有序,将另一边无序的一个数据项插入有序部分的合适位置。
例:2 4 7 5 8 3 6 1→2 4 5 7 8 3 6 1
一边是局部有序的(即有序部分数据项仍可能要移动)。
比较 | 交换 | 复制 | |
---|---|---|---|
冒泡排序 | O(N²)(或(N-1)N/2次) | O(N²)(或(N-1)N/4次) | —— —— |
选择排序 | O(N²)(或(N-1)N/2次) | O(N)(或N-1次) | —— —— |
插入排序 | O(N²)(或(N-1)N/4次) | —— —— | 同比较次数 |
冒泡排序效率最低,但最简单;插入排序效率最高,但最复杂。
三种排序的时间复杂度均为O(N²)。
特点:先进后出(FILO),只能操作(或访问,一般地)栈顶的数据。
操作:出栈pop、入栈push
效率:都为O(1)
判断栈空或者满:top == -1;top == maxSize
典型应用:单词倒序、匹配括号
特点:先进先出(FIFO),只能操作(或访问,一般地)队头数据。
类型:一般队列、循环队列、双端队列(两端均可插入或移除,了解)、优先级队列
循环队列:类似一个圆环,当front或rear等于maxSize时赋值为0,保证队列空间的完全利用。
优先级队列:按优先级排序的队列,优先级高的优先出列。(类似有序数组,但排序与数值无关)
操作:插入insert、移除remove
效率:都为O(1)(优先队列的插入操作为O(N))
判断队列空或满:
循环队列:front == rear;(rear+1)%maxSize == front
优先级队列:front == 0(类似栈一端固定)
中缀表达式:运算符处于两操作数之间的表达式。
后缀表达式:运算符处于两操作数之后的表达式。
中缀表达式转后缀表达式原理(基于简单二元运算符和括号):
使后缀表达式中第一个运算符和其前两个操作数对应中缀表达式中首先进行的操作,依次类推。
例:3+5*2 → 352*+、(3+2)*(4-1)→32+41-*
优先级:( ) > *、/ > +、-
键盘输入:
public static String getString() throws IOException{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
提炼自《Java数据结构与算法》第二版Robert Lafore.中国电力出版社