首页 > 编程语言 >【算法】分治初步

【算法】分治初步

时间:2023-08-22 12:44:28浏览次数:37  
标签:sort return 基准值 int 分治 mid 初步 算法 排序

目录

定义

分治,字面上的解释是“分而治之”,就是把一个问题分成多个的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。

示例

快速排序

把原数组分成左右两段,保证左 \(≤\) 右,再对左右分别排序。

实现

怎么才能让左不大于右呢?

基准值:左/右/中点/随机位置的值。 这么草率?

反正都一样。

对 \([l,r]\) 区间排序:

  1. i = l, j = r; 确定基准值x;
  2. i向后走,当 a[i]>x 时停下,j向前走,当 a[j]>x 时停下。
  3. if(i < j) swap(a[i], a[j]);
  4. 当i<j时,回到第二步。
  5. 对 \([l, j]\) 和 \([i, r]\) 分别递归,直到 l >= r
$\color{green}{\text{点击查看代码}}$
void quick_sort(int l, int r)
{
	int i = l, j = r;
	int x = a[(l+r)/2]; // 基准值(此处取中点,一般建议随机数)
	while(i<=j)
	{
		while(a[i] < x) i++;
		while(a[j] > x) j--;
		// i 表示小于基准值的下标,j 表示大于基准值的下标
		// 找到不满足以上的 a[i], a[j]
		if(i<=j) // 如果 i 在 j 左边,a[i] 和 a[j] 交换
		{
			swap(a[i], a[j]);
			i++,j--; // 防止越界 RE
		}
	}
	if(l<r) // 如果数列可以再分,递归
	{
		quick_sort(l,j);quick_sort(i,r);
	}
}

第k小

同快速排序。

但我们可以考虑一些神奇的方法。

对 \([l,r]\) 区间排序,找第 \(k\) 小:

qsort(l,r,k)
{
	选基准值,做交换。
	if(k <= j) return qsort(l,j,k);
	else if(k >= i) return qsort(i, r, k);
	else return x;
}
$\color{green}{\text{点击查看代码}}$
int quick_sort_mink(int l,int r,int k)
{
	int i = l, j = r;
	int x = a[(l+r)/2];
	while(i<=j)
	{
		while(a[i] < x) i++;
		while(a[j] > x) j--;
		if(i<=j)
		{
			swap(a[i],a[j]);
			i++,j--;
		}
	}
	if(k <= j) return quick_sort_mink(l,j,k);
	else if(k >= i) return quick_sort_mink(i,r,k);
	else return x;
}

三分法

例题:P1883 函数

归并排序

先对左右子区间排序,然后再把两个有序子区间合并成一个完整区间。

时间复杂度:稳定的 \(O(n \log n)\)。

实现

当前区间 \([l,r]\) :

  1. mid=(l+r)/2;
  2. 递归 \([l,mid]\) ;
  3. 递归 \([mid+1,r]\) ;
  4. 合并 \([l,mid],[mid+1,r]\) ;
$\color{green}{\text{点击查看代码}}$
void merge_sort(int l, int r)
{
	if(l >= r) return; // 不可再分就不继续了
	int mid = (l+r)/2;
	merge_sort(l, mid);
	merge_sort(mid+1, r);
	// 递归左右区间
	int i = l, j = mid+1; // 从两区间左端点开始
	int cnt = l-1;
	while(i <= mid && j <= r)
	{
		if(a[i] <= a[j]) b[++cnt] = a[i], i++;
		else b[++cnt] = a[j], j++;
		// 把a[i],a[j]更大的那个放进临时数组b[]
	}
	while(i <= mid) b[++cnt] = a[i], i++;
	while(j <= r) b[++cnt] = a[j], j++;
	// 把没放完的放进b[]
	for(int k = l;k <= r;k++) a[k] = b[k];
	// 把b[] 放回原区间
}

标签:sort,return,基准值,int,分治,mid,初步,算法,排序
From: https://www.cnblogs.com/ghivan911/p/17645723.html

相关文章

  • knn 算法的实现原理是怎样的
    K最近邻(K-NearestNeighbors,简称KNN)算法是一种用于分类和回归的基本机器学习算法。其原理是基于样本之间的距离度量,通过找出离待预测样本最近的K个训练样本,利用这K个样本的标签信息进行分类或回归预测。主要思想就是物以类聚人以群分的思想,关键就是KNN中K近邻中K的确定,和距离的定义......
  • java笔试手写算法面试题大全含答案
    1.统计一篇英文文章单词个数。publicclassWordCounting{publicstaticvoidmain(String[]args){try(FileReaderfr=newFileReader("a.txt")){intcounter=0;booleanstate=false;intcurrentChar;while((currentChar=fr.read())!=-1){if(currentChar=='......
  • java笔试手写算法面试题大全含答案
    1.统计一篇英文文章单词个数。publicclassWordCounting{publicstaticvoidmain(String[]args){try(FileReaderfr=newFileReader("a.txt")){intcounter=0;booleanstate=false;intcurrentChar;while((currentChar=fr.read())!=-1){if(currentChar==�......
  • 用 Dijkstra 算法解决最短路问题
    话不多说,先看图1.1朴素版的Dijkstra算法一般用到这个情况稠密图,也就是节点的个数比边的个数少。(稠密图用邻接矩阵存储)#include<cstring>#include<iostream>#include<algorithm>usingnamespacestd;constintN=510;intn,m;intg[N][N];//稠密图用邻接矩阵,g......
  • 【校招VIP】java语言考点之垃圾回收算法
    考点介绍:垃圾回收算法是必考题。GC中的垃圾指的是存在于内存中的、不会再被使用的对象。而垃圾回收就是把那些不再被使用的对象进行清除,收回占用的内存空间......一、考点题目1、java中如何判断对象是否是垃圾?解答:引用计数:在对象中添加一个引用计数器,如果被引用计数器加1,引用......
  • 加密算法分类
    密码加密算法针对密码存储的加密算法通常会使用一些特定的哈希函数或密码学技术,以确保用户密码在存储时是安全的。bcrypt:这是一种基于Blowfish加密算法的密码哈希函数。它适用于存储密码,因为它的加密强度可以根据需要进行调整,以抵御暴力破解和彩虹表等攻击。scrypt:与bc......
  • [Trick] [算法学习笔记] 线段树
    事先声明:本文并非线段树教学。只是一些理解Trick。若您需从0学起线段树建议您移步其他博文呢qwq感谢Idea提供尺子姐姐的博客!,尺子好闪,拜谢尺子!我们在学习线段树的时候,对于乘法“lazytag先乘再加”是不是难以理解?这里介绍一种线段树思考方法。我们可以将序列中的每个元素......
  • 【数据结构】排序 内部排序算法的比较和应用
    1.简单复习一下前面学到的排序算法三种插入排序:直接插入:依次将后面无序序列中头部的元素插入前面的有序序列中(找到插入位置,这个位置后面的元素一律后移)折半插入:相比直接插入只是用折半查找的方式查找插入位置,元素的移动操作不变希尔排序:把相隔一定步长d的元素放入一个子表......
  • 蒙特卡洛算法代码
    蒙特卡洛算法是一个常用的解题方法之一。以下是一个简单的蒙特卡洛求解圆周率π的代码示例:点击查看代码importrandomdefmonte_carlo_pi(n):count=0total=nfor_inrange(n):#在单位正方形内随机生成点的坐标x=random.unifor......
  • CDQ 分治
    定义CDQ分治作为一种思想,主要在解决形如\([l,r]\)区间中找符合要求的点对\((i,j)\)的问题时应用。具体的思想是:先递归解决\([l,mid]\)和\([mid+1,r]\)中的点对;再计算\(l\lei\lemid<mid+1\lej\ler\)的点对\((i,j)\)数量。例题例1:P3810【模板】三维偏序(陌......