算法导论第三版开始啃

还是要对得起自己的学历,回归算法,虽然难,但只要坚持下去,相信就会一片光明。。。吾辈岂是蓬蒿人!

第一部分基础
1、插入排序
2、归并排序
在这里插入图片描述
分治法
思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后再合并这些子问题的解来建立原问题的解。
3、分治策略
分解(Divide)步骤将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小。
解决(Conquer)步骤递归地求解出子问题。如果子问题的规模足够小,则停止递归,直接求解。
合并(Combine)步骤将子问题的解组合成原问题的解。

4、最大子数组问题
假定要寻找子数组A[low…high]的最大子数组。使用分治技术意味着要将子数组划分为两个规模尽量相等的子数组。找到数组的中央位置。比如mid,A[low…high]的任何连续子数组A[i…j]所处的位置必然是以下三种情况之一:
(1)完全位于子数组A[low…mid]中,因此low<=i<=j<=mid.
(2)完全位于子数组A[mid+1…high]中,因此mid<i<=j<=high.
(3)跨越了中点,因此low<=i<=mid<j<=high.
分析(1)、(2)两个子问题仍是最大子数组问题。只是规模更小。
跨越中点的子数组都由两个子数组A[i…mid]和A[mid+1…j]组成,其中low<=i<=mid且mid<j<=high.找出形如A[i…mid]和A[mid+1…j]的最大子数组 ,然后将其合并即可。
过程FIND-MAX-CORSSING-SUBARRAY接收数组A和下标low、mid和high为输入,返回一个下标元组划定跨越中点的最大子数组的边界,并返回最大子数组中值的和。

跨越中点的最大子数组
在这里插入图片描述
在这里插入图片描述
1-7行求出左半部A[low…mid]的最大子数组。8-14行求右半部A[mid+1…high]的最大子数组。
第15行返回下标max-left和max-right,划定跨越中点的最大子数组的边界,并返回子数组A[max-left…max-right]的和left-sum+right-sum.
求解最大子数组问题的分治算法的伪代码:
在这里插入图片描述

5、矩阵乘法的Strassen算法。
矩阵加法就是相同位置的数字加一下。
在这里插入图片描述
减法与之类似。

矩阵乘法:
矩阵乘以一个常数,就是所有位置都乘以这个数。

在这里插入图片描述

但是,等到矩阵乘以矩阵的时候,一切就不一样了。

在这里插入图片描述

这个结果是怎么算出来的?

教科书告诉你,计算规则是,第一个矩阵第一行的每个数字(2和1),各自乘以第二个矩阵第一列对应位置的数字(1和1),然后将乘积相加( 2 x 1 + 1 x 1),得到结果矩阵左上角的那个值3。

在这里插入图片描述

也就是说,结果矩阵第m行与第n列交叉位置的那个值,等于第一个矩阵第m行与第二个矩阵第n列,对应位置的每个值的乘积之和。
有三组未知数x,y和 t,其中 x 和 y 的关系如下
在这里插入图片描述
x 和 t 的关系如下:
在这里插入图片描述
有了这两组方程式,就可以求 y 和 t 的关系。从矩阵来看,很显然,只要把第二个矩阵代入第一个矩阵即可。

在这里插入图片描述
从方程式来看,也可以把第二个方程组代入第一个方程组。
在这里插入图片描述
上面的方程组可以整理成下面的形式。
在这里插入图片描述
最后那个矩阵等式,与前面的矩阵等式一对照,就会得到下面的关系。
在这里插入图片描述
在这里插入图片描述
SQUARE-MATRIX-MULTIPLY
在这里插入图片描述
第3-7行的for循环计算每行中的元素,在第i行中,第4-7行的for循环计算每列中的每个元素cij。第5行将cij初始化为0,开始按(4.8)公式中的求和计算,第6-7行的for循环每步迭代将公式(4.8)中的一项累加。i表示下标行,j表示下标列 ,k为公式(4.8)中的下标矩阵a 的列,矩阵b的行。

分治算法,计算矩阵乘法:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
不优于直接的SQUARE-MATRIX-MULTIPLY过程 。
在这里插入图片描述
创建如下的10个子矩阵。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从实用的角度看,Sreassen算法通常并不是解决矩阵乘法的最好选择,原因如下:

在这里插入图片描述
概率分析和随机算法
1、雇佣问题
排序和顺序统计量
1、堆排序
2、快速排序
3、线性时间排序
4、中位数和顺序统计量

数据结构
集合作为计算机科学的基础,就如同他们在数学中所起的作用。
一、基本数据结构
1、栈和队列
栈和队列都是动态集合,且在其上进行DELETE操作所移除的元素是预先设定的。在栈(stack)中,被删除的是最近插入的元素:栈实现的是一种后进先出(last-in,first-out,LIFO)策略。在队列(queue)中,被删去的总是在集合中存在时间最长的那个元素:队列实现的是一种先进先出(first-in,fist-out,FIFO)策略。

栈上的INSERT操作称为压入(PUSH),而无元素参数的DELETE操作称为弹出(POP)。
可以用一个数组S[1…n]来实现一个最多可容纳n个元素的栈。S[1]栈底元素,S[S.top]是栈顶元素。

在这里插入图片描述
栈的几种操作。


STACK-EMPTY(S)
1 if S.top==0
2 return TRUE
3 else rerurn FALSE


PUSH(S,x)
1 S.top=S.top+1
2 S[S.top]=x


POP(S)
1 if STACK-EMPTY(S)
2 error “underflow”
3 else S.top=S.top-1
4 return S[S.top+1]


队列

队列上的INSERT操作称为入队(ENQUEUE),DELETE操作称为出队(DEQUEUE)
DEQUEUE操作也没有元素参数。队列的先进先出特性类似于收银台前排队等待结账的一排顾客。队列有队头(head)和队尾(tail)。
2、链表
链表(linked list )是一种这样的数据结构,其中的各对象按线性顺序排列。数组的线性顺序是由数组下标决定的,然而与数组不同的是,链表的顺序是由各个对象里的指针决定的。链表为动态集合提供了一种简单而灵活的表示方法,并且能支持(添加、删除)等操作。
双向链表(doubly linked list)L的每个元素都是一个对象,每个对象有一个关键字key和两个指针:next 和 prev 。对象中还可以包含其他的辅助数据。设x为链表的一个元素,x.next 指向他在链表中的后继元素,x.prev则指向他的前驱元素。如果x.prev=NIL,则元素x没有前驱,因此是链表的第一个元素,即链表的头(head)。如果x.next=NIL,则元素x没有后继,因此是链表的最后一个元素,即链表的尾(tail).
L.head=NIL,则链表为空。
在这里插入图片描述
在这里插入图片描述
3、指针和对象的实现

4、有根数的表示

二、数据结构
散列表
二叉搜索树
红黑树

高级设计和分析技术
1、动态规划
通常用来解决最优化问题,在这类问题中,我们通过做出一组选择来达到最优解。在做出每个选择的同时,通常会生成与原问题形式相同的子问题。当多于一个选择子集都生成相同的子问题时,动态规划技术通常就会很有效,其关键技术就是对每个这样的子问题都保存其解,当其重复出现时即可避免重复求解。
2、贪心算法
贪心算法通常用于最优化问题
3、摊还分析

注:如果有博友想要这本电子版的书,可以留邮箱

自己还年轻,每天进步一点点。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值