首页 > 编程语言 >C++ 三路快排 模板

C++ 三路快排 模板

时间:2023-03-09 15:12:17浏览次数:42  
标签:右移 arr val int C++ 快排 三路 模板

前言:今天被大作业的快速排序折磨的焦头烂额,原 C++ sort 选手发现简洁的快排竟然如此难写(边界要注意的点好多 qwq)。

我原先的快排长这样:题解 P1177 【【模板】快速排序】 - 沧海之耀 的博客 - 洛谷博客 (luogu.com.cn)

三路快排:快速排序 - OI Wiki (oi-wiki.org)

先在 arr[l,r] 中随机一个 val

快排当前层的目标是将数值分为 < val | = val | > val 三类,也按这个顺序分开,然后分别递归 < val> val 两类。

算法思路:

  • 在工作过程中,维护 arr[l,r] 的这样一个性质。

    arr[l,j) < val | arr[j,i) = val | arr[i,k] 未分类 | arr(k,r] > val

    只要从左到右扫描 i ,直至 arr[i,k] 为空即可。

  • 变量定义

    • i : 要分类的对象 (从左到右扫描) , [l,i) 是已经分类好的 < val | = val

    • j : arr[l,j) < val, arr[j,i) = valj 表示 第一个 值为 val 的下标,若暂时没有 =val 的值,则 j=i

    • k : 维护一个右侧 > val 的垃圾堆。(k,r]> val 的部分

  • 工作流程:

    • 从左到右扫描

    • arr[i] > val 的放到右侧(与 arr[k] 交换),这里 i 不能右移,因为 换过来的arr[k] 还要判断。

    • arr[i] < val 的与 arr[j] 交换,i 右移,j 右移,维护 arr[l,j) < val, arr[j,i) = val

    • arr[i] = val ,不动,i 右移即可。

  • 具体实现:

// 三路快排 
void qsort(int arr[],int l,int r)
{
	if(l>=r) return;
	int i=l,j=l,k=r;
	int val=arr[l+rand()%(r-l+1)];

	while(i<=k) {
		if(arr[i]<val) 
			swap(arr[i++],arr[j++]); // 这里可,前面是安全的。 
		else if(val<arr[i]) 
			swap(arr[i],arr[k--]); // 这里 i 不能 ++, 还要判断一下后面扔过来的东西。 
		else i++;
	}
	
	qsort(arr,l,j-1); qsort(arr,k+1,r);
}
  • 时间复杂度分析:

    • 每次循环 \(i\) 增加或 \(k\) 减少,于是每层 \(O(len)\)

    • 总共 平均 \(O(n\log n)\)

这样实现三路快排, 比较好的解决了相同值多,或者选到最小或最大的 val 导致问题规模不缩小的问题。排序一次问题规模必缩小 。

标签:右移,arr,val,int,C++,快排,三路,模板
From: https://www.cnblogs.com/cjl-world/p/17198484.html

相关文章

  • c++常见的几种锁
    std::mutex(C++11),普通互斥锁,可以阻塞式等锁(lock())也可以非阻塞式上锁(try_lock())std::timed_mutex(C++11),互斥锁的加时版本,如果在一段时间内(try_lock_for())或是在某个时间......
  • 【C++】网上购书平台完善
    问题描述收到了一份室友已经完成的网上购书平台程序,对其功能使用和熟悉后,进行了部分功能的添加,使其更加完善。程序概况书店登录界面  部分功能展示    ......
  • c++移动构造函数
    一.介绍1.1 定义【源对象资源的控制权全部移交给目标对象】有些复制构造是必要的,我们确实需要另外一个副本;而有些复制构造是不必要的,我们可能只是希望这个对象换个地方,......
  • c++ 性能分析
    本文记录下日常工作中用到的性能分析工具。一、内存泄漏排查我的服务依赖了jemalloc,这个地方记录下使用jemalloc进行内存分析的方法。1编译jemalloc首先,依赖的je......
  • P3378 【模板】堆
    P3378【模板】堆【模板】堆题目描述给定一个数列,初始为空,请支持下面三种操作:给定一个整数x,请将x加入到数列中。输出数列中最小的数。删除数列中最小的数(如果有......
  • 【C++】购书系统问题测试&功能补充
    代码来源:舍友大一的C++作业【代码存在的问题】在菜单界面选择对应序号时,若输入值非数字,而是字母等其它符号,会导致程序陷入循环,无法正常进入功能的下一步     ......
  • [Primer] 第 14 章 C++ 中的代码重用
    第14章C++中的代码重用14.1包含对象成员的类类初始化列表中有多个项目时,初始化的顺序为在类中的声明顺序而不是列表顺序。14.2私有继承使用私有继承,基类的所有公......
  • gcc 编译 C/C++ 文件
    gcc编译C/C++文件众所周知,C/C++程序想要得到执行,主要需要执行编译和链接两个过程,这个过程比较繁琐,尤其是程序使用到了其他的头文件的时候。gcc是常用的编译工具,其流程主要......
  • 设计模式(十七)----行为型模式之模板方法模式
    行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为......
  • (P01)C++介绍
    文章目录​​1.需要掌握的重要练习​​​​2.为什么要学习C++​​​​3.C++为什么难学​​​​4.C++11值得学习的新特性​​​​5.几本推荐学习C++的书​​​​6.开发工具......