算法设计与分析期末考试复习(二)

news2025/7/19 16:55:32

分治法

将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。最好使子问题的规模大致相同。

  1. 分解(Divide):将一个难以直接解决的大问题,分割成一些规模较小的子问题,这些子问题互相独立,且与原问题相同。
  2. 递归求解子问题,若问题足够小则直接求解。
  3. 将各个子问题的解合并得到原问题的解。

求二叉树深度

int get_depth(BTPtr pbt){
	int dL,dR=0;
	if(pbt == NULL){
		return 0;
	}
	if((!ptb->lchild) && (!ptb->rchild)){
		return 1;
	}
	dL = get_depth(pbt->lchild);
	dR = get_depth(pbt->rchild);
	return 1 + ((dL>dR)?dL:dR);
}

分治法所能解决的问题一般具有四个特征:

  1. 该问题的规模缩小到一定的程序就可以容易地解决。
  2. 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
  3. 利用子问题的解可以合并得到原始问题的解。
  4. 各个子问题是相互独立的。

二分搜索技术,每执行一次算法while循环,待搜索数组的大小减少一半,因此最坏时间复杂度O(log n)

int BinarySearch(int a[],int x,int left,int right){
	while(left <= right){
		int mid = (left + right)/2;
		if(a[mid] == x){
			return mid;
		}else if(a[mid] < x){
			left = mid + 1;
		}else{
			right = mid - 1;
		}
	}
	return -1;
}

Master定理(递归复杂度判定定理)

在这里插入图片描述
大整数的乘法:将两个n位大整数相乘
传统逐位相乘、错位相加的传统方法:O(n2),效率太低。
分治法:将该问题分解为若干个规模较小的相同问题。
在这里插入图片描述
在这里插入图片描述
为了降低时间复杂度,必须减少乘法的次数。
在这里插入图片描述
在这里插入图片描述
两个XY复杂度都相同,但(a+b),(c+d)可能得到(n/2)+1位的结果,使问题的规模变大,故不选择第2种方案。

矩阵乘积的传统算法,时间复杂度O(n3)

void multi(int A[],int B[],int C[]){
	for(int i=1; i<=n ;i++){
		for(int j=1;j<=n;j++){
			C[i][j] = 0;
			for(int k=1 ;k<=n; k++){
				C[i][j] += A[i][k]*B[k][j];
			}
		}
	}
}

分治法:矩阵乘法
在这里插入图片描述
在这里插入图片描述
为了降低时间复杂度,必须减少乘法的次数。
在这里插入图片描述
棋盘覆盖问题:在一个2kx2k个方格组成的棋盘中,要求用图(b)所示的4种L形态骨牌覆盖给定的特殊棋盘,覆盖给定特殊棋盘上除特殊方格以外的所有方格,任何2个L型骨牌不得重叠覆盖。
在这里插入图片描述
分治策略技巧:使每个子棋盘均包含一个特殊的方格,从而将原问题分解为规模较小的棋盘覆盖问题。
在这里插入图片描述
棋盘覆盖问题中数据结构的设计:

  1. 棋盘:用二维数组board[size][size]表示一个棋盘,其中size=2k。为了在递归处理的过程中使用同一个棋盘,将数组board设为全局变量。
  2. 子棋盘:在棋盘数组board[size][size]中,用子棋盘左上角的tr、tc和棋盘边长s表示。
  3. 特殊方格:用board[dr][dc]表示,dr和dc是该特殊方格在棋盘数组board中的下标。
  4. L型骨牌:一个2k×2k的棋盘中有一个特殊方格,所以,用到L型骨牌的个数为(4k-1)/3,将所有L型骨牌从1开始连续编号,用一个全局变量t表示。
void ChessBoard(int tr,int tc,int dr,int dc,int size){
	if(size == 1)	return; //棋盘只有一个方格,且是特殊方格。
	t++;//L型骨牌号,已经初始化为0。
	s = size/2;//划分棋盘
	if(dr<tr+s && dc<tc+s){ //特殊方格在棋盘左上角
		ChessBoard(tr,tc,dr,dc,s);
	}else{ //用t号L型骨牌覆盖右下角,再递归处理子棋盘
		board[tr+s-1][tc+s-1] = t;
		ChessBoard(tr,tc,tr+s-1,tc+s-1,s);
	}
	
	if(dr<tr+s && dc >= tc+s){
		ChessBoard(tr,tc+s,dr,dc,s);
	}else{
		board[tr+s-1][tc+s] = t;
		ChessBoard(tr,tc+s,tr+s-1,tc+s,s);
	}

	if(dr>=tr+s && dc<tc+s){
		ChessBoard(tr+s,tc,dr,dc,s);
	}else{
		board[tr+s][tc+s-1] = t;
		ChessBoard(tr+s,tc,tr+s,tc+s-1,s);
	}

	if(dr >= tr+s && dc >= tc+s){
		ChessBoard(tr+s,tc+s,dr,dc,s);
	}else{
		board[tr+s][tc+s] = t;
		ChessBoard(tr+s,tc+s,tr+s,tc+s,s);
	}
}
  1. 当k>0时,将2的k次幂乘以2的k次幂分隔成为4个2的k-1次幂乘以2的k-1次幂子棋盘。
  2. 特殊方格必位于4个较小棋盘之一中,其余3个子棋盘中午特殊方格。
  3. 为了将这3个特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌将这3个较小棋盘的汇合处覆盖,这3个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将原问题转换成4个较小规模的棋盘覆盖问题。递归地使用这种分割,直至棋盘简化为1*1棋盘。

在这里插入图片描述

快速排序:在数组中确定一个记录作为划分元,将数组中关键字小于划分元的记录移动到划分元之前,将数组中大于划分元的记录移动到划分元之后。

int Partition(int *arr,int L,int R){
	int left = L;
	int right = R;
	int pivot = arr[left];
	while(left < right){
		while(left<right && arr[right]>=pivot)
			right--;
		if(left < right){
			arr[left] = arr[right];
		}
		while(left<right && arr[left]<=pivot)
			left;
		if(left<right){
			arr[right] = arr[left];
		}
		if(left == right){
			arr[left] = pivot;
			return left;
		}
	}
}

void QuickSort(int *arr,int L,int R){
	if(L < R){
		int position = Partition(arr,L,R);
		quickSort(arr,L,position-1);
		quickSort(arr,position+1,R)
	}
}

最好情况:T(n)=O(nlogn)(每次总是选到中间值作为划分元)
最坏情况:T(n)=O(n2)(每次总是选到最小或最大元素作为划分元)
算法性能与系列中关键字的排列顺序和划分元的选取有关

  1. 当初始序列按关键字有序(正序或逆序)时,快速排序蜕化为冒泡排序,此时算法性能最差,时间复杂度为O(n2)。
  2. 可以用“三者取中”法来选取划分元,设:数组首记录为r[s]、尾记录为r[t],取:r[s]、r[t]和r[(s+t)/2]三者的中间值为划分元。
  3. 也可采用随机选取划分元的方式

快速排序算法的性能取决于划分的对称性。通过修改算法partition,可以设计出采用随机选择策略的快速排序算法。在a[p:r]中随机选出一个元素作为划分基准,这样可以使划分基准的选择是随机的,从而可以期望划分是比较对称的。

int RandomizedPartition(int a[],int p,int r){
	int i = random(p,r);
	swap(a[i],a[p]);
	Partition(a,p,r)
}

线性时间选择:给定线性序集中n个元素和一个整数k,要求找出这n个元素中第k小的元素,问是否可以在O(n)时间内得到解决,可以采用分治法,模仿快排对输入数组进行递归划分,只对划分出的子数组之一进行递归处理,子数组的选择与划分元和k相关。

int RandSelect(int A[],int start,int end,int k){
	if(start == end){
		return A[start];
	}
	int i = RandomizedPartition(A,start,end);
	int n = i-start+1;//左子数组的个数
	if(k <= n){
		RandSelect(A,start,n,k);
	}else{
		RandSelect(A,i+1,end,k-n;)
	}
}

线性时间内找到合理划分基准的步骤(select函数)

  1. 将n个元素划分成n/5个组,每组5个元素,只有可能一个组不是5个元素。
  2. 用任意一种排序算法对每组中的元素排序。
  3. 取出每组中的中位数,共n/5个元素。
  4. 递归调用select函数,找出这n/5元素中的中位数。
  5. 如果n/5为偶数,就选择2个中位数中较大的一个,以这个选出的元素作为划分基准。

按递增序列,找出下面29个元素的第18个元素:
8,31,60,33,17,4,51,57,49,35,11,43,37,3,13,52,6,19,25,32,54,16,5,41,7,23,22,46,29.

  1. 把前面29个元素分为6组(ceil(29/5));(8,31,60,33,17),(4,51,57,49,35),(11,43,37,3,13),(52,6,19,25,32),(54,16,5,41,7),(23,22,46,29).
  2. 提取每一组中的中值元素,构成集合{33,49,13,25,16,29}
  3. 递归地使用该算法求得集合中的中值,得到m=29.
  4. 根据m=29,把29个元素划分为3个子数组P={8,17,4,11, 3,13,6,19, 25,16,5,7,23,22},Q={29},R={31,60,33,51,57,49,35,43,37,52,32,54,41,46}
  5. P中有14个元素,Q中有1个元素,所以18-15=3,对R递归地执行本算法。
  6. 将R划分成3组(ceil(14/5)):{31,60,33,51,57},{49,35,43,37,52},{32,54,41,46}
  7. 求取这3组元素的中值元素分别为{51,43,46},这个集合的中值是43.
  8. 根据43将R划分成3组{31, 33, 35,37,32, 41},{43},{60, 51,57, 49, 52,54, 46}
  9. 因为k=3,第一个子数组的元素个数大于k,所以放弃后面两个子数组,以k=3对第一个子数组递归调用本算法;
  10. 将这个子数组分为5个元素为一组: {31,33,35,37,32}、{41},取中值为33。
  11. 根据33,把第一个子数组划分成{31,32},{33},{35,37};
  12. 因为k=3,而第一、第二个子数组的元素个数为3,所以33即为所求取的第18个小元素。
int Select(int a[],int start,int end,int k){
	if(end-start<75){
		//用某个简单的算法对数组a[start:end]排序
		return a[start+k-1];
	}
	for(int i=0; i<=(end-start-4)/5; i++){
		//将a[start+5*i]与a[start+4+5*i]的第3小元素与a[start+i]交换位置
	}
	//找出中位数中的中位数
	int x = Select(a,start,start+(end-start-4)/5,(end-start-4)/10);
	int i = Partition(a,start,end,x); //划分元位置
	int n = i-start+1; //左数组长度
	if(k <= n)	return Select(a,start,i,k);
	else{
		return Select(a,i+1,end,k-n);
	}
}

在这里插入图片描述

最接近点对:给定平面上的n个点,找出其中的一对点,使得在n个点组成的所有点对中,该点对的距离最小。

直观解法:将每一个点与其他n-1个点的距离算出,找出最小距离,时间复杂度:T(n)=n(n-1)=O(n2)
分治法

  1. 分解:将n个点的集合分成大小近似相等的两个子集。
  2. 求解:递归求解两个子集内部的最接近点对。
  3. 合并:从子空间内部最接近点对,和两个子空间之间的最接近点对中,选择最接近点对。
    在这里插入图片描述

分治法

  1. 假设我们用x轴上某个点m将S划分为2个子集S1和S2,基于平衡子问题的思想,用S中各点坐标的中位数来作分割点。
  2. 递归地在S1和S2找出其最接近点对{p1,p2}和{q1,q2}。
  3. 设d=min{|p1-p2|,|q1-q2|},则S中的最接近点对可能是{p1,p2},或者是{q1,q2},或者是某个{p3,q3},其中p3∈S1且q3∈S2。
  4. 如果最接近点对是{p3,q3},即|p3-q3|<d:即p3和q3两者之间的基于不超过d,p3∈(m-d, m],q3∈(m, m+d]。
bool Cpair1(S,d){
	n = |S|;
	if(n < 2){
		d =;
		return false; 
	}
	m = S中各点坐标的中位数。
	构造S1和S2 //构造S1={x  S|x<=m}, S2={x  S|x>m}
	Cpair(S1,d1);
	Cpair1(S2,d2);
	p = max(S1);
	q = min(S2);
	d = min(d1,d2,q-p);
	return true;
}

考虑二维的情况
在这里插入图片描述

  1. 选取二维平面的一条垂直线L:x=m作为分割线,其中m为S中各点x坐标的中位数,由此将S分割成S1和S2。
  2. 递归地在S1和S2上找出其中最小距离d1,d2。
  3. 设d=min{d1,d2},S中的最接近点对间的距离或者是d,或者是某个点对{p,q}之间的距离,其中p∈S1且q∈S2。如果用符号P1和P2分别表示直线 L 的左右两边宽为d的区域,则必有p∈P1且q∈P2

在这里插入图片描述
考虑P1中任意一点p,它若与P2中的点q构成最接近点对的候选者,则必由distance(p,q)<d,P2中满足条件的点一定落在矩形R中,矩阵R的大小为dx2d。
由d的定义可知:P2中任何2个点(qi∈S)的距离都不小于d,由此可以推出矩形R中最多只有6个S中的点。
在分治法的合并步骤中最多只需要检查6×n/2=3n个候选者

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/368830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

个人电脑需求严重疲软,联想集团财务前景仍不乐观

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 财务业绩 联想集团&#xff08;00992&#xff09;于2月16日盘后公布了2023财年第三季度财报。 财报显示联想集团2023年第三季度的收入为152.67亿美元&#xff0c;从2022年第三季度的2011.27亿美元下降了24.1%。这也导致该公…

那些开发中需要遵守的产研开发规范

入职新公司第三天&#xff0c;没干啥其他活&#xff0c;基本在阅读产研开发规范。公司在技术方面沿用的是阿里的一套技术&#xff0c;所以入职之前需要先阅读《阿里巴巴开发规范》。今天整理一些平时需要关注的阿里规约和数据库开发规范&#xff0c;方便今后在开发过程中查阅。…

如何判断你的孩子是否适合IB课程?

IB课程最开始是IBO为外交官子女开设全球统一标准的课程&#xff0c;后为全球学生开设从幼儿园到大学预科的课程&#xff0c;为学生提供智力、情感、个人发展、社会技能等方面的教育。IB课程分为标准难度课程和具有挑战性的高难度课程。要求学生至少选择6门课加Theory of Knowle…

Java 日期时间与正则表达式,超详细整理,适合新手入门

目录 1、java.time.LocalDate类表示日期&#xff1b; 2、java.time.LocalTime类表示时间&#xff1b; 3、java.time.LocalDateTime类表示日期和时间&#xff1b; 4、java.time.format.DateTimeFormatter类用于格式化日期和时间&#xff1b; 5、创建正则表达式对象 6、匹配…

spring-boot、spring-cloud、spring-cloud-alibaba版本对应

一、查询 spring-boot(spring-boot-starter-parent) 版本号 https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent 二、查询 spring-cloud(spring-cloud-dependencies) 版本号 https://mvnrepository.com/artifact/org.springframework…

NPC内网穿透教程-入门

安装 安装包安装 releases下载 下载对应的系统版本即可&#xff0c;服务端和客户端是单独的 源码安装 安装源码 go get -u ehang.io/nps 编译 服务端go build cmd/nps/nps.go 客户端go build cmd/npc/npc.go docker安装 server安装说明 client安装说明 启动 服务端 下…

企业容器云管理平台选型指南

作者简介 涂家英&#xff0c;SUSE 资深架构师&#xff0c;专注 Cloud-Native 相关产品和解决方案设计&#xff0c;在企业级云原生平台建设领域拥有丰富的经验。 数字时代下的容器云管理平台 数字时代&#xff0c;市场竞争加剧&#xff0c;业务需求日新月异&#xff0c;敏态 IT…

Java常用日期类(包含三代)_Date类及Calendar类等

一.java.util.Date类概述从JDK 1.0出现。表示一个日期和时间&#xff0c;精确到毫秒&#xff0c;内部getTime()从1970年1月1号开始算。1. java.util.Date类构造部份构造已经过时&#xff0c;重点看以下两个构造。public Date()从运行程序的此时此刻到时间原点经历的毫秒值&…

Java学习笔记 --- 正则表达式

一、体验正则表达式 package com.javase.regexp;import java.util.regex.Matcher; import java.util.regex.Pattern;/*** 体验正则表达式&#xff0c;给文本处理带来哪些便利*/ public class Regexp_ {public static void main(String[] args) {//假设&#xff0c;编写了爬虫&…

【2023】助力Android金三银四面试

前言 新气象&#xff0c;新生机。在2023年的Android开发行业中&#xff0c;又有那些新的面试题出现呢&#xff1f;对于Android面试官的拷问&#xff0c;我们又如何正确去解答&#xff1f;万变不离其宗&#xff0c;其实只要Android的技术层面没变化&#xff0c;面试题也就是差不…

江苏专转本考前焦虑自救指南

考前焦虑自救指南 考试即将来临&#xff0c;面对着人生里未知的门槛&#xff0c;我们的心里总是充满着各种迟疑&#xff0c;成功的对立面永远都充斥着各种不确定性。 陷入考前焦虑&#xff0c;需要立即调整状态。 1、将你的内心恐惧用笔写下来 这样做的目的就是&#xff0c;不要…

git的使用(终端输入指令) 上

git目录前言1.创建仓库2.创建文件和修改数据状态分区![分区](https://img-blog.csdnimg.cn/d124dec6b2b14769ad20b75490f29cae.png)3 .删除、撤销重置 、和比较前言 今天带大家手把手敲一遍 git 流程&#xff1a; 安装一下git&#xff08;详细观看我之前发的git文档&#xff0…

内网渗透(五十六)之域控安全和跨域攻击-非约束委派攻击

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

【无标题】智能工业安全用电监测与智慧能源解决方案

工业互联网已成为全球制造业发展的新趋势。在新基建的推动下&#xff0c;5G、人工智能、云计算等技术与传统工业深度融合&#xff0c;为实现智能制造提供了技术支撑&#xff0c;将有力促进制造强国早日实现。 十四五规划在新基建的基础上进一步加快了制造业转型升级的步伐&…

【添砖java】谁说编程第一步是hello world

编程第一步明明是下载编译器和配置环境&#xff08;小声逼逼&#xff09;。 Windows下的java环境安装&#xff1a; java的安装包分为两类&#xff0c;一类是JRE&#xff08;Java Runtime Environmental&#xff09;&#xff0c;是一个独立的java运行环境&#xff1b;一类是JDK…

《Linux运维实战:Centos7.6基于ansible一键离线部署rabbitmq3.9.16+haproxy高可用镜像模式集群》

一、部署背景 由于业务系统的特殊性&#xff0c;我们需要针对不同的客户环境部署 rabbitmqhaproxy高可用镜像模式集群&#xff0c;由于大都数用户都是专网环境&#xff0c;无法使用外网&#xff0c;为了更便捷&#xff0c;高效的部署&#xff0c;针对业务系统的特性&#xff0c…

RT-Thread移植到STM32F407

文章目录第一步&#xff1a;获取RT-Thread源码第二步&#xff1a;项目结构介绍第三步&#xff1a;拷贝示例代码到裸机工程第四步&#xff1a;删除无用文件第五步&#xff1a;修改工程目录结构第六步&#xff1a;添加工程文件路径第七步&#xff1a;编译第八步&#xff1a;修改配…

MySQL进阶篇之视图/存储过程/触发器

今天我们主要来快速学习视图&#xff0c;存储过程&#xff0c;触发器四个方面的内容&#xff0c;一起加油学习吧&#xff0c;还有半年就有秋招了&#xff0c;要加快速度了&#xff0c;迫在眉睫&#xff0c;冲吧&#xff0c;兄弟们。 目录 1、视图 2、存储过程 3、存储函数 4、…

Linux系统Nginx下载和安装

文章目录golang学习面试网站Linux启动nginx参考Linux启动nginx版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文链接&#xff1a;https://blog.csdn.net/weixin_36755535/article/details/110…

使用GDAL进行坐标转换

1、地理坐标系与投影坐标系空间参考中主要包含大地水准面、地球椭球体、投影坐标系等几部分内容。地图投影就是把地球表面的任意点&#xff0c;利用一定数学法则&#xff0c;转换到地图平面上的理论和方法&#xff0c;一般有两种坐标系来进行表示&#xff0c;分别是地理坐标系和…