【数据结构详解】——快速排序(动图详解)

❤️全面图解快速排序,详细图文并茂解析!❤️ 写在前面: 大家好,我是时光。 今天给大家带来的是排序算法中的快速排序。 我采用图解方式讲解,争取写透彻。话不多说,开始! 思维导图: 1,快速排序概念 通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。主要采用分治法和挖坑填数等方法,分治法就是大问题分解成各个小问题,堆小问题求解,使得大问题得以解决。 2,算法思路 我们先搞清楚这个堆排序思想,先把逻辑搞清楚,不着急写代码。 我们首先有一个无序数组,比方说 阅读详情
AI摘要

本文详细介绍了快速排序的各种实现方法,包括Hoare版本、挖坑法、前后指针法,并探讨了快速排序的优化策略,如三数取中法和小区间优化排序。

🕒 1. 快速排序

💡 算法思想:快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。

🕘 1.1 Hoare版本(左右指针法)

请添加图片描述

具体思路是:

  1. 选定一个基准值(pivot / key),最好选定最左边或者最右边;
  2. 确定两个指针left和right分别从左边和右边向中间遍历数组;
  3. 如果选最右边为基准值,那么left指针先走,如果遇到大于基准值的数就停下来。这样能保证相遇位置比基准值大;
  4. 然后右边的指针再走,遇到小于基准值的数就停下来;
  5. 交换left和right指针对应位置的值;
  6. 重复以上步骤,直到left = right ,最后将基准值与left(right)位置的值交换,这便完成一趟排序。

请添加图片描述

这样基准值左边的所有数都比它小,而它右边的数都比它大,从而它所在的位置就是排序后的正确位置。之后再递归排以基准值为界限的左右两个区间中的数,当区间中没有元素时,排序完成。
请添加图片描述

// 快速排序hoare版本
int PartSort(int* a, int left, int right)
{
	int key = right;// 选定基准值
	while (left < right)
	{
		// 选右边为基准值,则左指针先走,从左往右找到第一个比基准值大的元素
        while (left < right && a[left] <= a[key])
		{
			left++;
		}
 
        // 右指针再走,从右往左找到第一个比基准值小的元素
        while (left < right && a[right] >= a[key])
		{
			right--;
		}
		Swap(&a[left], &a[right]);
	}
	Swap(&a[left], &a[key]);
	return left;
}
 
void QuickSort(int* a, int left, int right)
{
    assert(a);
	if (left >= right)
	{
		return;	// 如果左边界大于等于右边界,表示已经排序完成。
	}
 
	
	int keyi = PartSort(a, left, right);	// 对数组进行一次分割操作,获取基准值的最终位置
	QuickSort(a, left, keyi - 1);			// 对基准值左边的子数组进行递归排序
	QuickSort(a, keyi + 1, right);			// 对基准值右边的子数组进行递归排序
}

🕘 1.2 挖坑法

💡 算法思想:挖坑法与上面Hoare版本思想基本一致,都是利用递归(即分治的算法思想)去实现排序。但挖坑法的不同之处在于,当left和right这两个下标在遍历过程中找到满足条件的元素时(即元素值大于或小于基准值key),它们会立即将这些元素放置到合适的位置,这个过程可以描述为边查找边替换。相比之下,Hoare版本则是先记录下符合条件的元素下标,在遍历完成后再进行位置的交换。

请添加图片描述

具体思路是:

  1. 先将选定的基准值(最左边)直接取出,然后留下一个坑;
  2. 当右指针遇到小于基准值的数时,直接将该值放入坑中,而右指针指向的位置形成新的坑位;
  3. 然后左指针遇到大于基准值的数时,将该值放入坑中,左指针指向的位置形成坑位;
  4. 重复该步骤,直到左右指针相等。最后将基准值放入坑位之中。

注意,在操作过程中,我们并不是真正地创建一个新的坑位,而是在逻辑上将其视为坑位。实际上,坑位仍然占据着原来的元素,我们只是在操作时暂时将原元素存储起来,然后用新元素直接覆盖它。在left和right最终相遇的位置,就会形成一个坑位,恰好可以放置key。

// 快速排序挖坑法
int PartSort(int* a, int left, int right)
{
    int key = a[left]; // 取出基准值
    int hole = left; // 保存坑的位置

    while (left < right)
    {
        // 从右向左找第一个小于基准值的元素
        while (left < right && a[right] >= key)
        {
            right--;
        }
        // 将找到的小于基准值的元素填入左边的坑中
        a[hole] = a[right];
        hole = right; 

        // 从左向右找第一个大于基准值的元素
        while (left < right && a[left] <= key)
        {
            left++;
        }
        // 将找到的大于基准值的元素填入右边的坑中
        a[hole] = a[left];
        hole = left; 
    }

    // 将基准值填入最后一个坑中,此时左右两部分已经分好
    a[hole] = key;

    return hole; 
}

void QuickSort(int* a, int left, int right)
{
    assert(a);
	if (left >= right)
	{
		return;	// 如果左边界大于等于右边界,表示已经排序完成。
	}
 
	int keyi = PartSort(a, left, right);	// 对数组进行一次分割操作,获取基准值的最终位置
	QuickSort(a, left, keyi - 1);			// 对基准值左边的子数组进行递归排序
	QuickSort(a, keyi + 1, right);			// 对基准值右边的子数组进行递归排序
}

🕘 1.3 前后指针法

💡 算法思想:有两个指针:cur、prev(cur的位置在prev的下一个位置),期间通过cur去遍历数组,将每个元素与key值比较大小,若发现有元素小于key,就让prev++(即走到下一个位置),再与cur此时对应的元素进行交换,通过递归的方式重复上述的步骤,即可实现完全排序。

简而言之:

  • prev和key初始位置之间的区间,是在维护一个所有元素都小于key的区域,目的是使key左侧的序列中的所有值都小于key。
  • prev++到cur之间的区间,则是在维护一个所有元素都大于key值的区域,以确保key右侧的序列中的所有值都大于key。
  • cur不断寻找小于key的元素并与prev++后的位置交换,是为了将序列后方小于key的元素移动到key前方,保证key左侧子序列的值都小于key,右侧子序列的值都大于key。

具体思路是:

  1. 选定基准值,定义prev和cur指针(cur = prev + 1);
  2. cur先走,遇到小于基准值的数停下,然后将prev向后移动一个位置;
  3. 将prev对应值与cur对应值交换;
  4. 重复上面的步骤,直到cur走出数组范围;
  5. 最后将基准值与prev对应位置交换;
  6. 递归排序以基准值为界限的左右区间。
    请添加图片描述
// 快速排序前后指针法
int PartSort(int* a, int left, int right)
{
    // 选择基准值为数组的第一个元素(left)
    int keyi = left; // 基准值索引
    int prev = left; // 前指针初始化为基准值的位置
    int cur = left + 1; // 后指针初始化为基准值后一个位置

    // 遍历数组,将小于基准值的元素交换到前面
    while (cur <= right)
    {
        if (a[cur] < a[keyi] && ++prev != cur)
        {
            Swap(&a[prev], &a[cur]); // 如果当前元素小于基准值,交换到前面
        }
        cur++; 
    }

    Swap(&a[prev], &a[keyi]); // 将基准值交换到最终位置

    // 选择基准值为数组的最后一个元素(right)
    /*
    int keyi = right; // 基准值索引
    int prev = left - 1; // 前指针初始化为左边界的前一个位置
    int cur = prev + 1; // 后指针初始化为左边界

    // 遍历数组,将小于基准值的元素交换到前面
    while (cur <= right)
    {
        if (a[cur] < a[keyi] && ++prev != cur)
        {
            Swap(&a[cur], &a[prev]); // 如果当前元素小于基准值,交换到前面
        }
        cur++; 
    }

    Swap(&a[keyi], &a[++prev]); // 将基准值交换到最终位置
    */
    
    return prev; 
    
}

void QuickSort(int* a, int left, int right)
{
    assert(a);
	if (left >= right)
	{
		return;	// 如果左边界大于等于右边界,表示已经排序完成。
	}
 
	int keyi = PartSort(a, left, right);	// 对数组进行一次分割操作,获取基准值的最终位置
	QuickSort(a, left, keyi - 1);			// 对基准值左边的子数组进行递归排序
	QuickSort(a, keyi + 1, right);			// 对基准值右边的子数组进行递归排序
}

🕘 1.4 快速排序的优化

快速排序是一种高效的排序算法,但在某些情况下存在缺陷。例如,若基准值选为最小值,则会引发不必要的递归。此外,对于大量有序或近似有序的数据排序时,快速排序效率较为低下,甚至可能导致程序崩溃,因为过多的递归调用可能会造成栈溢出。为了提高效率并避免这些问题,可以采用以下两种优化策略:

  1. 三数取中法选基准值
  2. 递归到小的子区间时,可以考虑使用插入排序

🕤 1.4.1 三数取中

💡 算法思想:即在选择基准值时,不是简单地选择数组的第一个元素或者最后一个元素,而是从当前子数组的第一个元素、中间元素和最后一个元素中选择中间大小的元素作为基准值。这种方法的优势在于:

  • 降低最坏情况的发生概率: 如果每次选取的基准值都是当前子数组中的中间值,那么快速排序在大多数情况下会有较好的性能表现,因为这样可以避免极端情况下分割不均匀的问题。
  • 减少递归深度: 选取较为中间的元素作为基准值,可以更均匀地划分数组,避免出现极端的递归深度,从而减少排序的时间复杂度。
// 三数取中法
int MidIndex(int* a, int left, int right)
{
    int mid = (left + right) / 2;	// 计算中间元素的索引
    // 若要防止整数溢出可以使用以下方式计算mid
    // int mid = left + (right - left) / 2;

    // 比较三个关键位置的元素,选出中间值的索引作为基准值
    if (a[left] < a[right])
    {
        if (a[mid] < a[left])
        {
            return left;
        }
        else if (a[mid] > a[right])
        {
            return right;
        }
        else
        {
            return mid;
        }
    }
    else
    {
        if (a[mid] > a[left])
        {
            return left;
        }
        else if (a[mid] < a[right])
        {
            return right;
        }
        else
        {
            return mid;
        }
    }
}
// 快速排序前后指针法优化
int PartSort(int* a, int left, int right)
{
	int mid = MidIndex(a, left, right);
	// 将基准位置调整至最左边
	Swap(&a[mid], &a[left]);

    // 选择基准值为left
    int keyi = left; 
    int prev = left; 
    int cur = left + 1; 
    ......
}

🕤 1.4.2 小区间优化排序

💡 算法思想:优化排序的时间复杂度,减少不必要的调用递归次数

具体来说,就是在完成一次快速排序递归后,将数据分为左右两个子序列。如果这两个子序列的数据量都较小,就可以直接采用更适合小数据集的排序方法,如插入排序,而不必再进行快速排序的递归操作。这样不仅提高了算法的效率,也优化了递归层次,特别是在数据量较小的情况下更为明显。

// 快速排序小区间优化
void QuickSort(int* a, int left, int right)
{
    assert(a);
	if (left >= right)
	{
		return;	
	}

	// 小区间优化,减少递归次数
	if (right - left + 1 < 10)
	{
		InsertSort(a + left, right -left + 1);
	}
	else
	{
		int keyi = PartSort(a, left, right);
		QuickSort(a, left, keyi - 1);
		QuickSort(a, keyi + 1, right);
	}
}

🕘 1.5 快速排序的非递归实现

💡 算法思想:快速排序的非递归实现依赖于栈来存储待排序的子区间。这种方法不仅避免了递归可能导致的栈溢出问题,而且其核心思想与递归实现是相似的。

具体思路是:

  1. 将数组左右下标入栈;
  2. 若栈不为空,两次取出栈顶元素,分别为闭区间的左右界限;
  3. 将区间中的元素按照上述任意一种方法得到基准值的位置;
  4. 再以基准值为界限,若基准值左右区间中有元素,则将区间入栈;
  5. 重复上述步骤直到栈为空。
void QuickSortNonR(int* a, int left, int right)
{
    // 创建栈
    Stack st;
    StackInit(&st);
 
    // 原始数组区间入栈
    StackPush(&st, right);  // 先将右边界入栈
    StackPush(&st, left);   // 再将左边界入栈
 
    // 将栈中区间排序
    while (!StackEmpty(&st))
    {
        // 弹出栈顶的左右边界
        left = StackTop(&st);
        StackPop(&st);
        right = StackTop(&st);
        StackPop(&st);
        
        // 对当前区间进行划分,得到基准值的位置
        int mid = PartSort(a, left, right);
 
        // 将基准值两侧的子区间入栈,准备下一轮排序
        if (right > mid + 1)
        {
            StackPush(&st, right);  // 右边界入栈
            StackPush(&st, mid + 1);  // 右侧子区间的左边界入栈
        }
        if (left < mid - 1)
        {
            StackPush(&st, mid - 1);  // 左侧子区间的右边界入栈
            StackPush(&st, left);  // 左边界入栈
        }
    }
    
    // 销毁栈
    StackDestroy(&st);
}

快速排序的特性总结:

  1. 快速排序整体的综合性能和使用场景都是比较好的,所以才叫快速排序。
  2. 时间复杂度:最好:O(N*logN) ; 最坏:O(N2)
  3. 空间复杂度:O(logN) ~ O(N)
  4. 稳定性:不稳定

❗ 转载请注明出处
作者:HinsCoder
博客链接:🔎 作者博客主页

快速排序(Quick sort) 一、简介 快速排序是(Quick sort)是对冒泡排序的一种改进,是非常重要且应用比较广泛的一种高效率排序算法。 二、算法思路 快速排序是通过多次比较和交换来实现排序,在一趟排序中把将要排序的数据分成两个独立的部分,对这两部分进行排序使得其中一部分所有数据比另一部分都要小,然后继续递归排序这两部分,最终实现所有数据有序。 大致步骤如下: 首先设置一个分界值也就是基准值又是也称为监视哨,通过该分界值将数据分割成两部分。 将大于或等于分界值的数据集中到右边,小于分界值的数据集中到左边。一趟排序过后,左边部 阅读详情

相关推荐

快速排序入门(动图演示)

快速排序时间复杂度是O(nlogn)

qq_40595682的博客 1万+

快速排序详解

在之前我们已经见识到了一些基础的排序算法,比如冒泡排序,选择排序,插入排序,堆排序,希尔排序了,对于以上的几种排序我们知道希尔排序和堆排序的时间复杂度更小一些,他们的算法优先性对于其他算法还是有很大的差别,而今天我们会介绍一个排序速度如其名的排序--快速排序。快速排序由C. A. R. Hoare在1962年提出,它是一种基于二叉树结构的交换排序算法,它采用了一种分治的策略,通常称其为分治法。

qq_61422622的博客 4万+

【排序算法】快速排序(四个版本以及两种优化)含动图)

详细介绍了快速排序的四种实现方式及代码

2301_80176226的博客 1892

排序——快速排序(Quick sort)

概况 快速排序(Quick sort)是对冒泡排序的一种改进。快速排序由C. A. R. Hoare在1960年提出。 算法思路 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 快速排序算法通过多次比较和交换来实现排序,其排序流程如下: ......

努力中的老周的专栏 32万+

算法介绍——快速排序

快速排序 快速排序是最常用的排序算法。 举例说明 假设我们要对 “6 1 2 7 9 3 4 5 10 8” 这 10 个数进行排序。 C代码实现 # 复杂度分析

程序员「阿基米东」的编程之旅 4万+

基于FPGA的数据采集系统(一)

整体系统设计 本设计主要是对ADC和DAC的使用,主要实现功能流程为:首先通过串口向FPGA发送控制信号,控制DAC芯片tlv5618进行DA装换,转换的数据存在ROM中,转换开始时读取ROM中数据进行读取转换。其次用按键控制adc128s052进行模数转换100次,模数转换数据存储到FIFO中,再从FIFO中读取数据通过串口输出显示在pc上。其整体系统框图如下: 图1:FPGA数据采集系统框图 从图中可以看出,该系统主要包括9个模块:串口接收模块、按键消抖模块、按键控制模块、ROM模块、D..

phflovelt的博客 2万+

快速排序(动图详解)(C语言数据结构)

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。快速排序有三个版本,将一一实现。

多敲代码防脱发的博客 1573

深入解析进化算法中的选择与多样性

在计算科学的世界里,最优雅的解决方案往往源于最古老的智慧——大自然。进化算法(Evolutionary Algorithms, EAs)正是这样一种受达尔文自然选择学说启发的强大工具。它们通过模拟“适者生存”的过程,在庞大的可能性海洋中搜寻最优解。。:指的是深入挖掘和优化已知的优质解。这就像在一片已知的沃土上精耕细作,力求获得最高产量。强大的选择压力会促进这一过程。:指的是在整个搜索空间中寻找全新的、可能更优的解。这好比派遣探险队去发现新大陆,充满了未知与机遇。保持种群的多样性是探索的关键。

weixin_62533513的博客 716

【数据结构从菜鸟到大牛】都2022了,我不允许你还不懂快速排序 <快速排序算法>【附动图详解~】【快排的三种版本~】【快排的优化】

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,最初是以递归形式实现的排序算法。 快速排序,作为以’快‘为名字的排序,我们必须要搞清楚他为什么快? 本文章一文带你搞懂,快速排序的基本原理,快速排序的3种实现方法 还有快速排序的优化,以及如何采用非递归的方法实现快速排序 ...

K_04_10的博客 647

内核工作FAST‘25 Artifact Evaluation流程记录

在我们的paper中,复现需要用到傲腾持久化内存,因此,需要AE Reviewer访问到内网服务器中。我们的思路是购买云服务器,将其作为跳板机,内网服务器通过SSH反向代理与公网服务器建立隧道,AE Reviewer通过隧道访问内网服务器。我们在AE过程中使用。然后,把一切复现需要的代码环境,在chroot里面配置完成。

不定期更新系统使用、编程小技巧,哔哩哔哩账号:https://space.bilibili.com/399455629,欢迎关注 1215

UVM自学笔记3——项目之三——从零开始搭建ahb_sramc验证平台

创建如下所示的目录结构: 2.在tb的文件下:顶层的testbench如下:在tb中,第24行的代码将uvm宏相关的内容include进来,第26行的代码把uvm_pkg包导入进来,然后将agent相关的包(ahb_pkg/sram_pkg),testcase相关的包(uvm_ahb_sram_test_pkg)以及env相关的包(uvm_ahb_sram_env_pkg)都导入进来,在第38行和39行将接口以virtual interface的形式配置给ahb_agent和sramc_agent下

ZhangShuHuai11的博客 9474

【C语言】-- 数据结构 -- 交换排序类(冒泡排序,快速排序)(超详解+动图+源码)

包括时间复杂度,空间复杂度,稳定性(带图讲解)

weixin_64609308的博客 1222

用LTspice仿真Buck电路输出电容:从参数计算到波形优化的全流程演示

本文详细介绍了使用LTspice仿真Buck电路输出电容的全流程,从理论计算到波形优化。通过解析关键参数如纹波电压、瞬态响应和ESR,结合工程计算方法和LTspice仿真技巧,帮助工程师优化Buck电路设计,解决输出纹波过大和瞬态响应不佳的问题。

night的博客 851

【数据结构】排序算法---快速排序(动图演示)

快速排序算法精讲,还含有动图演示

2301_80191662的博客 5186

本地部署 pyvideotrans(视频翻译配音工具)

语音识别选择faster-whisper(本地),模型选择预先下载并保存的medium,然后选择好要处理的视频以及保存到的位置,这里我选择了一个名为why not的英文演讲视频,保存在桌面_vedio_out文件下。将附件中faster-medium.7z 和 faster-small.7z解压到项目中的models目录下, 解压后,目录中应该存在 models--Systran--faster-whisper-small。en.m4a|.wav = 原始视频中的音频文件(包含所有背景音和人声)

西唯兵欧泡的博客 2341

SMOKE 3D:从 Python 到 C++ 实现车辆与行人单目 3D 视觉识别在 RK3588 上的深度部署

SMOKE的网络结构通常基于高性能的骨干网络(如DLA-34,您使用的模型就是基于此),通过编码器-解码器架构来提取特征。输入:RGB图像(本项目为骨干网络:用于特征提取。检测头热力图分支:预测关键点热力图。通常在热力图上进行NMS来找到局部最大值,即潜在的关键点位置。回归分支:对于每个关键点位置,预测上述的8维3D属性向量。分类分支:预测每个关键点对应的物体类别。置信度分支:预测每个关键点的置信度。本教程详细介绍了SMOKE单目3D目标检测模型在RK3588上的部署。我们从SMOKE的。

LXY_LOVE36的博客 436

【数据结构】常见八大排序算法(附动图)

本文围绕八种常见排序算法展开讲解,包含算法思想、动图、源代码和对算法的优化等

Eristic0618的博客 9992

PX4从放弃到精通(三):使用qt编译PX4

1 下载px4源码 2在Firmware所在目录下执行 mkdir Firmware-build cd Firmware-build cmake …/Firmware -G “CodeBlocks - Unix Makefiles” -DCONFIG=nuttx_px4_fmu-v5_default 第三步最后的px4_fmu-v5_default根据自己的情况修改 执行完后如图 打开QT 点击打开工程 选择源码的CmakeLists.txt文件 选择imported Kit 打开项目那一栏,构建目

超维空间科技的博客 1万+

数据结构初阶(15)排序算法—交换排序(快速排序)(动图演示)

排序算法—交换排序(快速排序)(动图演示)

2301_79907403的博客 1909

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Java经典排序算法:快速排序,动图演示排序过程

Java经典排序算法:快速排序,动图演示排序过程 示意动图: import java.util.Arrays; public class Main { public static void main(String[] args) { new Main().test(5); } private void test(int size) ...

Zhang Phil 1845

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

数据结构——排序算法之快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法。基本思想:任取待排序元素序列中 的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。递归实现方式常见有三种,区别于单趟思想,性能差别不大,下面我们看下快排递归实现。

zhoubancheng的博客 3960

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【数据结构】排序——快速排序

1.快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫。

m0_74091744的博客 1580

【数据结构--八大排序】之快速排序

快速排序,挖坑法,前后指针法,霍尔法。

luhaoran814的博客 1738

经典四大排序(动图实现)

这个大佬整理的很仔细: https://blog.youkuaiyun.com/m0_37741420/article/details/106981276?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162777450716780262565601%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=162777450716780262565601

Myblog 2万+

【数据结构详解】——归并排序(动图详解)

💡 算法思想:归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用**分治法**的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列。即先使每个子序列有序,再使子序列段间有序,若将两个有序表合并成一个有序表,称为**二路归并**。

HinsCoder的博客 1万+
上一篇: 【数据结构详解】——冒泡排序(动图详解)
下一篇: 【数据结构详解】——归并排序(动图详解)
HinsCoder
博客等级 码龄5年 1万+粉丝 220原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值