算法第二章
第二章
1、主方法
主方法是一个算法复杂度分析的一个很好的方法,但是只能用于特定的递归上,适合的递归形式为:
$$
T(n)=aT(n / b)+f(n)
$$
判断$n^{log b (a)}$与$f(n)$的大小关系
(1) 如果$n^{log b (a)}=O(f(n))$,那么该方法的复杂度为$O(f(n)*n^{log b (a)})$其中k>=0
(2) 如果$n^{log b (a)}>O(f(n))$,那么该方法的复杂度为$O(n^{log b (a)})$
(3) 如果$n^{log b (a)}<O(f(n))$,那么该方法复杂度为 $O(f(n))$
2、二分搜索
概念
二分搜索法,它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用$O(log n)$完成搜索搜索任务。它的基本思想是,将n个元素分成个数大致相同的两半,取$a[n/2]$与欲查找的x作比较,如果$x=a[n/2]$则找到x,算法运算终止。
代码
void binarySearch(vector<int> &array, int element)
{
int begin = 0;//begin代表的是,查找数组中的第一个元素的索引,初始为0
int end = array.size()-1;//end此时代表的是查找数组的最后一位元素索引
while (begin <= end)//当begin与end错过时,查找数组中不再有任何元素,搜索结束
{
int middle = (begin + end) / 2;
if (array[middle] == element)
{
cout << "Search Success Index = " << middle << endl;
return;
}
else if (element < array[middle])
{
end = middle -1;//更新end指针,指向新的搜索数组的末尾元素(不包括middle,所以要-1)
}
else if (element > array[middle])
{
begin = middle + 1;//更新begin指针,指向新的搜索数组的首元素(不包括middle,所以要+1)
}
}
cout<<"Element Not Find"<<endl;
return;
}
时间复杂度分析
⼆分搜索算法的时间复杂性满足:
$$
T(n)=\left{\begin{array}{cc}
1 & n=1 \
1+T\left(\frac{n}{2}\right) & n>1
\end{array}\right.
$$
$$
\begin{aligned}
&T(n)=T\left(\frac{n}{2}\right)+1=T\left(\frac{n}{2^2}\right)+1+1 \
&=T\left(\frac{n}{22}\right)+2=T\left(\frac{n}{23}\right)+1+2 \
&=T\left(\frac{n}{23}\right)+3=T\left(\frac{n}{2k}\right)+k\
&\text { 令 } n=2^k \text {; 则 } k=\log n \
&T\left(\frac{n}{2^k}\right)+k=T(1)+k=1+\log n
\end{aligned}
$$
⼆分搜索算法的时间复杂度为:$O(log(n))$
2-3 改写二分搜索算法
请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。设a[0:n-1]是已排好序的数组。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
template<class T>
int binarySearch(T a[],const T&x,int left,int right,int &i,int &j){
int middle;
while(1eft<=right){
middle=(1eft +right)/2;
if(x==a[middle]){
i=j= middle;
return i;
}
if (x> a[middle])
left=middle+1;
else
right=middle-1;
}
i=right;
j=1eft;
return 0;
}
3、大整数的乘法
m*n位大数时间复杂度为$O(mn)$
将n位二进制整数x和y都分为两段,每段的长为$\frac{n}{2}$
$$
\begin{aligned}
&X=A 2^{\frac{n}{2}}+B \
&Y=C 2^{\frac{n}{2}}+D
\end{aligned}
$$
$$
X Y=\left(A 2^{\frac{n}{2}}+B\right) \times\left(C 2^{\frac{n}{2}}+D\right)=A C 2^n+(A D+B C) 2^{\frac{n}{2}}+B D
$$
$$
\begin{aligned}
&T(n)=\left{\begin{array}{cc}
O(1) & n=1 \
4 T\left(\frac{n}{2}\right)+O(n) & n>1
\end{array}\right. \
&T(n)=O\left(n^2\right)
\end{aligned}
$$
时间复杂度没有下降
对$XY$乘积式进行修改
$$
X Y=A C 2^n+((A-B)(D-C)+A C+B D) 2^{\frac{n}{2}}+B D
$$
时间复杂度改变
$$
\begin{aligned}
&T(n)=\left{\begin{array}{cc}
O(1) & n=1 \
3 T\left(\frac{n}{2}\right)+O(n) & n>1
\end{array}\right. \
&T(n)=O\left(n^{\log _2 3}\right)=O\left(n^{1.59}\right)
\end{aligned}
$$
2-4 大整数乘法的 $O(nmlog(3/2))$算法
给定两个大整数u和v,它们分别有m和n位数字,且 m≤n用通常的乘法求uv的值需要$O(mn)$时间。可以将u和v均看作有n位数字的大整数,用本章介绍的分治法,在$ O(n^{log3})$时间内计算uv的值。当m比n小得多时,用这种方法就显得效率不够高。试设计一个算法,在上述情况下用 $O(nm^{log(3/2)})$时间求出uv的值。
当m比n小得多时,将v分成n/m段,每段m位。计算uv需要n 次m位乘法运算。每次m位乘法可以用主教材中的分治法计算,耗时 $O(mlog3)$。因此,算法所需的计算时间为
$$O((n/m)m{log3})=O(nm)$$
4、合并排序
合并排序,大致思想便是先将数组中的元素拆分成若干小部分,然后再将这些小部分按照顺序进行重新组合,从而实现排序。
时间复杂度分析
$$
T(n)=\left{\begin{array}{cc}
O(1) & n=1 \
2 T\left(\frac{n}{2}\right)+O(n) & n>1
\end{array}\right.
$$
$$
T(n)=O(n \log n)【主定理、递归】
$$
$$
\begin{aligned}
T(n) &=2 T\left(\frac{n}{2}\right)+c n=2\left(2 T\left(\frac{n}{4}\right)+c \frac{n}{2}\right)+c n \
&=2^2 T\left(\frac{n}{2^2}\right)+2 c n \
&=\cdots \
&=2^k T\left(\frac{n}{2^k}\right)+k c n
\end{aligned}
$$
$$
\begin{aligned}
\text { 令 } n &=2^k, k=\log n \
T(n) &=2^k T(1)+c n \log n \
&=O(n \log n)
\end{aligned}
$$
5、快速排序
快速排序算法通过多次比较和交换来实现排序,其排序流程如下:
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于分界值,而右边部分中各元素都大于或等于分界值。
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
时间复杂度
- 最坏(正好按照正序或逆序)
$$
\begin{gathered}
T_{\max }(n)=\left{\begin{array}{cc}
O(1) & n=1 \
T(n-1)+O(n) & n>1
\end{array}\right. \
\longrightarrow T_{\max }(n)=O\left(n^2\right)
\end{gathered}
$$
- 最好(每次划分后都产⽣⼤⼩为n/2的两个区域)
$$
\begin{gathered}
T_{\min }(n)=\left{\begin{array}{cc}
O(1) & n=1 \
2 T\left(\frac{n}{2}\right)+O(n) & n>1
\end{array}\right. \
\rightarrow T_{\min }(n)=O(n \log n)
\end{gathered}
$$
本文作者:Is_zx
本文链接:https://www.cnblogs.com/erxuerxu/p/16659975.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步