0x05算法设计与分析复习(二):算法设计策略-分治法4
参考书籍:算法设计与分析——C++语言描述(第二版)
算法设计策略-分治法
选择问题
问题描述
选择问题(select problem)是指在n个元素的集合中,选出某个元素值大小在集合中处于第k位的元素,即所谓的求第k小元素问题(Kth-smallest)。
分治法求解
如果使用快速排序中所采用的选取主元的分划方法,以主元为基准,将一个表划分为左右两个子表。设原表的长度为n,经过一趟划 分,分成左右两个子表,其中左子表时主元及其左边的元素的集合,长度为p;右子表是主元右边元素的集合。那么,如果
//Select 函数 //随机选主元算法 //假定表中元素各不相同,并且随机选择主元,即在下标区间[left,right]中随机选择一个下标r,以该下标处的元素为主元。 template<class T> ResaultCode SortableList<T>::Select1(T& x, int k) { if(n<=0 || k>n || k<=0) return OutOfBounds; int left = 0, right = n; l[n] = INFTY;//INFITY是一个大值 do{ int j = rand()%(right-left+1)+left;//随机选择主元 Swap(left,j);//将主元交换至位置left处 j=Partition(left,right);//执行分划操作 if(k==j+1){//找到 x=l[j]; return Success; } else if(k<j+1){ right = j; } else{ left = j+1; } }while(true); }
上述算法与快速排序有相同的最坏情况时间复杂度
线性时间选择算法*
下面是最坏情况下具有线性时间的求第k小元素的算法。
改进的选择算法采用二次取中法(median of medians rule)确定主元。通过精心挑选分划元素,可以使得所得的两个子集合的大小相对接近,从而使得求第k小元素的最坏情况时间具有线性时间
//线性时间选择算法 ResultCode SortableList<T>::Select(T& x, int k) { if(n<=0||k>n||k<=0) return OutOfBounds; int j=Select(k,0,n-1,5); x=l[j]; return Success; } template<class T> int SortableList<T>::Select(int k, int left, int right, int r) { int n = right-left+1; //若问题足够小,使用直接插入排序,取其中的第k小元素,其下标为left+k-1 if(n<=r){ InsertSort(left, right); return left+k-1; } for(int i = 1;i<n/r; i++){ //二次取中规则求每一组的中间值 InsertSort(left+(i-1)*r,left+i*r-1); //将每组的中间值集中存放在子表前部 Swap(left+i+1,left+(i-1)*r+Ceil(r,2)-1); } int j = Select(Ceil(n/r,2),left,left+(n/r)-1,r);//求二次中间值,其下标为j Swap(left,j);//二次中间值为主元,并换至left处 j=Partition(left,right);//对表进行分划操作 if(k==j-left+1) return j;//返回k小元素下标 else{ if(k<j-left+1) return Select(k,left,j-1,r);//在左子表中求第k小元素 else return Select(k-(j-left+1),j+1,right,r);//在右子表中求第k-(j-left+1)小元素 } }
斯特拉森矩阵乘法
普通的矩阵乘法算法的时间复杂度为
分治法
假定n是2的幂,
如果子矩阵还不够小,则还需要进一步划分,直到每个子矩阵只含有一个元素,可以直接计算其乘积。
但是这种分治法的时间复杂度仍为
斯特拉森分治法
斯特拉森通过减少子矩阵的乘法次数来降低时间复杂度。其处理方式是,先执行7次子矩阵的乘法和10次加(减)法得到7个中间子矩阵:
然后再使用8次子矩阵加(减)法得到:
于是
在Strassen之后又有许多算法改进了矩阵乘法的计算时间复杂性。目前最好的计算时间上界是
O(n2.376)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)