一、基本内容
1、算法的意义与重要性
好的程序具有:正确性、可拓展性、安全性、健壮性、可维护性以及算法等
2、时间复杂度与大O表示法
大O表示法定义:对于给定的函数g(n),用O(g(n))来表示以下函数的集合:O(g(n))={f(n):存在正常量c和n0,使得对所有n≥n0,有0≤f(n)≤cg(n)}。我们使用的O记号来给出函数的一个在常量因子内的上界
时间比较:O(1) < O(log n) < O(n) < O(n log n) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)
复杂时间法则:
类型 | 取值法则 |
---|---|
for循环 | 从里到外,类似于剥洋葱形式 |
顺序语句 | 各个运行时间求和 |
if/else语句 | 路径最长时间 |
二、主题内容
1、二分查找法
概念:在某一有序数组中查找某一特定元素的搜索算法
步骤:
1.如果中间元素正好是要查找的元素,则搜索过程结束
2.如果某一特定元素大于或者小于中间元素,则在对应的子数组中查找,再次比较中间元素是否相同
3.若出现某一步骤数组为空,则代表没有找到
2、数组与链表
特点:数组,有序且连续;链表,可连续也可不连续
复杂度比较:
操作 | 链表 | 数组 |
---|---|---|
查找 | O(n) | O(1) |
头部插入/删除 | O(1) | O(n) |
尾部插入/删除 | O(n) | O(1) |
中间插入/删除 | O(n) | O(n) |
3、循序表
特点:是数组和链表的结合体
4、链表
类型 | 特点 |
---|---|
单向链表 | 是数组和链表的结合体,包含头指针和尾指针 |
双向链表 | 是数组和链表的结合体,包含头节点和尾节点,每一个节点都指向一个前驱和后继 |
5、栈和队列
类型 | 特点 |
---|---|
栈 | 先进后出(LIFO) |
队列 | 先进后出(FIFO) |
栈方法:
1.S.push(e):压入栈中
2.S.pop:弹出栈
3.S.top():查询顶部元素
4.S.is_empty():检查栈是否包含元素
5.len(S):检查栈的长度
队列方法:
1.Q.enqueue(e):队尾插入
2.Q.dequeue():队头去除
3.Q.first():查询对头元素
4.Q.is_empty():检查栈是否包含元素
5.len(Q):检查栈的长度
循环队列:避免了队列空间浪费的弊端
双端队列:支持队列的头部和尾部进行插入和删除操作
双端队列方法:
1.D.add_first(e):对头插入
2.D.add_last(e):对尾插入
3.D.delete_first(e):对头删除
4.D.delete_last(e):对尾删除
5.D.first():查询头部元素
6.D.last():查询尾部元素
4.D.is_empty():检查是否包含元素
5.len(D):检查的长度
6、排序
选择排序
特点:1.运行时间和输入无关;2.数据移动是最少的
时间复杂度:O(n2);空间复杂度:O(1)
冒泡排序
特点:运行时间和输入无关;
时间复杂度:O(n2);空间复杂度:O(1)
插入排序
特点:运行时间和输入有关;
希尔排序
结合分组和不长进行插入排序比较
归并排序
对两个不同的数据进行排序进行
快速排序
随机挑出基准值,进行排列