思想:
习题:
18.1
log2N
18.2
若第一次比较两边一样重说明不存在
多比较一次 ,第二次比较时,质量相同的一边排除,记下相同的质量即可
18.3
第二章好像算过
18.4
因为具体实现还是一样的,只是化为小方块相乘
18.5
当K==1 时, 就是此值
18.6
看总结
18.7
1)
2)
A的左上行,B的左上列
18.8
填充颜色时,用上一节的贪婪算法+
18.9
带入公示即可 不断的乘4 一共有k个
18.10
满足, 因为此fx二阶导数是正的,所以是凹的,增率一定是变大的
18.11
应该也是成立的 ,但用什么方法呢
18.44
合并具体实现变了,变成融合两个单链表了
18.13-16
17-18
编写一个标志数组,记录相对有序的下标 ?融合合并
Natural Merge Sort(自然归并排序) - 燃烧少年的心 - 博客园 (cnblogs.com)
17.19-20
21:
与上面程序一样就行了,边界改一下
22:
1)因为是往左边(或右边)循环到底,每一次都是一半,所以只需要logN
23:
当递增时,left和right都要一共遍历n个元素 一共n趟
24:
分一半,必然是nlogn
25:
部分积分
带入即可证明
26:
肯定好很多 ,结果大概率都是中间元素
27:
srand函数生成下标值
28:
可以,根据不同的规模,实际时间也不一样
29:
1) 首先最小实例顺序是反的 然后反递归,顺序也是反的
比如 87,21,65,43
2) 某一实例对于哪一种算法来说是最坏的呢?
3) stable_sort()与sort()的用法区别_云守护的专栏-CSDN博客_stable_sort
4) 看总结0
30,31:
32:
n个cn相加 线性的
33:
因为是中间的中间,所以轴点不会太离谱
34:
带进去递归即可
35:
尾部递归都能换成迭代,更新边界即可
36:
1,带入即可
37:
dist函数不用sqrt
38:
不能对每一个点测相邻的距离吗 O(n)
39:
1) 使K= n/2 然后调用select 寻找点 ; 其他依旧
2) nlongn
3) 不会
40:
n^logba == a^k k也就是递归的次数
我们猜测解是O(nlogn),我们要寻找到一个常数c,使得
T(n)<=cnlogn<=a^logn/2+kg(n)<=a^logn+kg(n) == a^logn+logbn*g(n)<= a^k*(t(1)+g(n))
41:
带入a b logba ,套表即可
42:
分为三种集合 a :最大候选者,b:可能最大候选者:c:不可能为最大者
初始a集合为n :a两元素 比较 ,一个进b 一个进c
最快方法: a中比较 n/2 次 b中比较 n/2-1次 一共 n-1 次 ,即为下限
43
n/2之后每一项都比n/2 大
44-45
略,自己照着书画
46
就是线性代数的逆序数
1) 3+1+1 =5
2) n-1+n-2+...+1 == n(n-1)/2
3)分为2种集合 a b a:最坏序列 b:以确定最大的序列
由于每一个相邻都需要比较 第一趟n-1次比较 入b
最终比较 n-1+n-2+....+1 -> Ω(n^2)
47
1) n个节点 n-1条边
n+1(加入外部节点) 到根 就有n条边 每个叶节点有两个外部节点 所以 2n 条边
所以多2n条边
数学归纳法证明 E = I + 2n
当n为1时,I = 0; E = 2; 满足 E = I + 2n
当有n个内结点时设公式成立,则当有 n + 1个内结点时(相对于n个内结点时增加一个外结点) ,令增加了一个内结点后二叉树的高为 h(不包含外结点)、内路径长度 I(n+1) = I(n) + h , 外路径长度E(n+1) = E(n) - h + 2(h+1),又有E(n) = I(n) + 2n, 整理得 E(n+1) - h - 2 = I(n+1) - h + 2n 即有E(n+1) = I(n+1) + 2(n+1)
证毕
2)
节点相同多时,完全二叉树高度最小,所以路径最短
3)
p+1是高度h
2^(p+1) 是高度为h最多 总节点数
然后。。。不会了
4)
E=(n+1)p-2^(p+1)+2n+2
5)
共有2^(p+1)条外部路径 ,带入即可
总结:
0.排序总结:
图表 :
:可以根据n的值来选择具体排序的方法
1 Strassen矩阵乘法
详解矩阵乘法中的Strassen算法_u011250186的博客-CSDN博客_strassen矩阵乘法
2 归并排序
分为n/k 个相对有序序列 然后归并 直至只有一个序列
当K ==2 时,次数最少 ,成为归并排序 :
直接归并:
分为递归和迭代
自然归并:
按对内数据进行划分序列
#include<iostream>
using namespace std;
template<class T>
void
merge(T *c,T *d,int startOfFirst,int endOfFirst,int endOfSecond){ // 合并两个有序序列
int first=startOfFirst,
second=endOfFirst+1,
result=startOfFirst;
while(first<= endOfFirst && second <=endOfSecond){
if(c[first]<=c[second])
d[result++]=c[first++];
else d[result++]=c[second++];
}
if(first>endOfFirst)
for(int k=second;k<=endOfSecond;k++)
d[result++]=c[k];
else
for(int k=first;k<=endOfFirst;k++)
d[result++]=c[k];
}
template<class T>
void
mergePass(T *x,T* y,int n,int segmentSize){
int start=0;
while(start<=n-2*segmentSize){ // 循环 确定边界 使数组内所有块排序
merge(x,y,start,start+segmentSize-1,start+ 2*segmentSize-1);
start=start+ 2*segmentSize;
}
if(start+ segmentSize<n){
merge(x,y,start,start+segmentSize-1,n-1);
}
else
for(int j=start;j<n;j++)
y[j]=x[j];
}
template<class T>
void
mergeSort(T* a,int n){
T* b=new T[n];
int segmentSize=1; //开始序列长度为1
while(segmentSize<n){
mergePass(a,b,n,segmentSize);
segmentSize += segmentSize;
mergePass(b,a,n,segmentSize);
segmentSize+= segmentSize;
}
delete [] b;
}
int main(){
int element[]={-9999,88,57,999,-2,55,32,-6};
mergeSort(element,sizeof(element)/sizeof(element[0]));
for(int i=0;i<8;i++)
cout<<element[i]<<" ";
cout<<endl;
}
3 快速排序
可以使用 三值取中 来进行快速排序,避免最坏情况
4 找出第K小的元素
利用归并排序
当 a【lefrEnd】 交换到 a【j】,那么a【leftEnd】 便是第 j-leftEnd+1 小元素 并且==k
就返回
如果 j-leftEnd+1<k ,那么目标就在右半边 k-j+leftEnd-1 小的元素
else 就在左半边 第k小元素
中间的中间 选择支点
5 相距最近的点对
两点之间距离公示:
我们由此出发,寻找距离最近的点对,只要从 |x-x1| 和 |y-y1| 两个方面来考虑
设计四个结构{
point :数据成员为 x,y 分别代表横坐标,纵坐标
point1: 从point派生 : x,y, 增添 id 定义了一个double类型的转换 ,返回横坐标x的值 用于排序
point2: 同上 ,返回y坐标 排序
pointPair :内涵 两个point类型成员(代表两点),和一个dist(两点之间距离 )
}
若使用直接法,计算每对点之间的距离 ,复杂度为O(n^2)
我们设计另外一种方法 :
1 划分为两边 A区和B区 ,点数大致相等
如何划分:
取x横坐标 ,利用point1类型的数组进行排序 取中间,相当于一条中垂线
2 分别寻找A区和B区内 相距最短点对(两点同区)
利用递归算两区内最大值 a,b
取a,b两个值的较小者记为S
3 一个点在A 一个点在B 最短点对, 从三者中选最短即可
步骤:
1)
因为最短长度目前已经为S,所以当离中垂线(分割线)的距离大于S时,总距离必不可能小于S(因为还要加上y的距离)
--》所以只要画出离中垂线 +- S 的距离区域 ,其余区域的点排除(筛选横坐标)
2)
这时分为两个点的集合Ra ,Rb 分,对于 一个集合中的点,算出距另一个集合中点的距离:
由于S目前最短距离 ,所以Ya-Yb大于S时,总距离必不可能小于S(因为还要加上X的距离)
--》 所以只要比较距Ya +- S 的区域 ,其余区域排除 (筛选纵坐标)
具体实现 :
利用分而治之 ,最小实例为2 ,当小于4时直接计算相互之间的距离,>=4 分为小实例
代码:
closestPair:
计算一个点在A一个点在B点:
6. 求递归方程(套表公式法)
要点: 找到a,b
算logb a
套公式计算h()
查找到f()带入即可
递归式求解的三种方法_l-jobs的专栏-CSDN博客_主方法求解递归式
7 问题的复杂度上下限