读书笔记 |《算法图解》

数据结构

具体描述

数组

在内存中一段连续的空间存储相同类型的数据,数组相邻元素之间的内存地址的间隔一般就是数组数据类型的大小。

链表

1、补一定要连续的存储空间
2、每个节点包含了数据和指向下一节点的地址
3、优点:便于数据插入和删除
4、缺点:不方便查找,每次查找都需要从头开始遍历

跳表

添加多级索引的链表,目的是为了便于链表的查找

特点:先进后出

队列

特点:先进先出

1、完全二叉树
2、满二叉树
3、平衡二叉树
4、红黑二叉树

堆通常是一个可以被看做一棵树的数组对象。堆的具体实现一般不通过指针域,而是通过构建一个一维数组与二叉树的父子结点进行对应,因此堆总是一颗完全二叉树。

散列表

散列表也叫哈希表,是一种通过键值对直接访问数据的机构。
既:一个数据通过某种映射(函数关系)存放在特定位置,目的是方便查找

常用算法

二分查找

1、应用
数据快速查找
2、思路

  1. 数据有序排列
  2. 取数组中间的元素,与查找对象比较
  3. 缩小查找范围
  4. 找到数据

在有序的数据中,循环不断对比数据中间元素与被查找值的关系,直至找到该元素
节约查找时间
在这里插入图片描述

3、实现代码

# list-数据   item-查找对象
def binary_search (list, item):
	low = 0
	high = len(list)-1
	while low <= high:
		mid = (low + high)/2
		guess = list[mid]
		if guess == item:
			return mid
		if guess > item:
			high = mid - 1
		else:
			low =mid + 1
	return None

4、详解
二分法查找

选择排序

1、应用
数据排序,按照一定的规则(例如:从大到小)
2、思路
采用最简单的方法:
1、遍历每一个元素,找出最小的哪个;
2、重复上述操作,直到最后一个元素;
在这里插入图片描述

3、实现代码


void Select_Sort(int* arr)   //arr为数据数组
{
	n = len(arr)
	for (int i = 0; i < n; i++) {
		int min = i;
		for (int j = i; j <= n; j++) {
			if (arr[min] > arr[j]) {
				min = j;
			}
		}
		if (min != i) {
			swap(arr[i], arr[min]);
		}
	}
}

4、详解
选择排序

快速排序

1、应用
数据快速排序
2、思路
1、从数组中选取(随机)选取一个元素,称为基准值;
2、遍历,把数组分成两组数组(一组中的元素比基准值大,另一组的元素比基准值小);
3、不断重复1、2步骤,直至分出来的两组元素的个数不大于2个;
与二分法查找类似,但是由于数据本身无规则,所以无法取中间值,只能随机取元素做基准值。最坏情况下要的时间长度为 O ( n 2 ) O(n^2) O(n2),平均时间长度 O ( n l o g 2 n ) O(nlog_2 n) O(nlog2n)
在这里插入图片描述

3、实现代码

def quicksort(array):
	if len(arrat) < 2:
		return array
	else:
		pivot = array[0]
		less = [i for i in array[1:] if i <=picot]
		greater = [i for i in array[1:] if i> pivot]
		return quicksort(less) + [pivot] + quicksort(greater)

4、详解
快速排序

广度优先搜索

1、应用
查找两样东西之间最短的“距离”(经历最少的元素,从a到b)
能回到的问题有:
<1>元素A 是否有路径到达元素B
<2>元素A 到元素B 最少需要经历多少节点
2、思路
1、从A出发,罗列所有能到达的元素,即二级元素,查找是否有元素B
2、若无,再从二级元素出发,罗列能到达的所有元素,即三级元素,查找是否有元素B
3、循环,直至找到元素B,即找出路径
4、若无元素罗列,则元素A无法到达元素B
在这里插入图片描述

3、实现代码

#graph-字典,存放元素间的关系 例:‘name’:['name1','name2''name3']
def search (name):
	search_queue = deque()
	search_queue += graph[name]
	searched = []		#记录检查过的人
	while search_queue:
		person = search_queue.popleft()
		if person not in searched:
			print person + 'is a mango seller!'
			return True
		else:
		search_queue += graph[person]
		searched.append(person)
	return False

4、详解
广度优先搜索

狄克斯特拉算法

广度优先搜索,路径加权。
参考

贪婪算法

不考虑整体,每一步都采取最优解。专业术语就是每步都选择局部最优解。
优点:简单易行
缺点:缺乏全局观,从整体出发贪婪算法存在不是最优解的可能性。
参考1
参考2

动态规划

动态规划

K最近邻算法

“分类”算法
例:
A可能是苹果,也可能是橘子,现在要做的是分辨A是什么?
B、C、D 三个是苹果
E、F、G 三个是橘子
分别计算出A与B、C、D、E、F、G的距离(特征距离,数据需归一化处理,否则某一特征会变成主要影响,也可为特征加权),取距离最近的K个元素,从而判断A是苹果还是橘子。
换句话说(KNN):
1、特征提取
2、特征数据归一化
3、特征加权
4、距离计算(欧式距离、马氏距离、曼哈顿距离、余弦距离…)
5、选取距离最近的K个元素
6、分类
其实这也是个概率问题,但是但特征越多,明显特征越突出,分类的正确率将会随之提高,但是特征过多或造成过度耦合。
简单示例

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值