• C++快排 ~ 三种实现方法


    1、前言

    快排的理论部分,有兴趣者可点击博客 温故而知新 -> 数据结构 ->排序 或通过其他方式进行理解!
    博主其实之前实现过快排,具体可见博客 温故而知新 -> 数据结构 ->排序 ->程序实现2_利用C++ 中的内容,但因为当时实现是函数之间的层层调用,虽然理解不难,但代码量会比较多,也有点麻烦,所以在本篇博客中将对其进行精简!

    快排中,将区间按照基准值划分为左右两半部分的常见方式有:

    1. hoare版本
    2. 挖坑法
    3. 前后指针版本

    所以下面的程序实现将按这三种方法进行说明!

    2、代码

    2.1 hoare 版本

    2.1.1 代码

    #include 
    #include 
    using namespace std;
    
    void display(vector<int>& arr)
    {
    	for (auto& n : arr)
    		cout << n << " ";
    	cout << endl;
    }
    // 将数组以升序进行排列!
    void quickSort(vector<int>& arr, int left, int right) // hoare  升序
    {
    	if (left >= right)
    		return;
    	int key = arr[left];
    	int begin = left;
    	int end = right;
    	int start = left;
    	while (begin < end)
    	{
    		while (begin < end && arr[end] >= key)
    			--end;
    		while (begin < end && arr[begin] <= key)
    			++begin;
    		if (begin != end)//此句是用于减少不必要的操作,可加可不加
    			swap(arr[begin], arr[end]);
    	}
    	swap(arr[start], arr[begin]);
    	quickSort(arr, left, begin - 1);//此处begin与end可任选其一
    	quickSort(arr, begin + 1, right);
    }
    // 将数组以降序进行排列!
    void quickSort_2(vector<int>& arr, int left, int right) // hoare  降序
    {
    	if (left >= right)
    		return;
    	int key = arr[left];
    	int begin = left;
    	int end = right;
    	int start = left;
    	while (begin < end)
    	{
    		while (begin < end && arr[end] <= key)
    			--end;
    		while (begin < end && arr[begin] >= key)
    			++begin;
    		if (begin != end)//此句可加可不加
    			swap(arr[begin], arr[end]);
    	}
    	swap(arr[start], arr[begin]);
    	quickSort_2(arr, left, begin - 1);//此处begin与end可任选其一,因为上面的循环结束后,begin会与end相等
    	quickSort_2(arr, begin + 1, right);
    }
    void test()
    {
    	vector<int> arr = { 6, 3, 1, 8, 7, 2, 4 };
    	cout << "原数组:"; display(arr);
    	quickSort(arr, 0, arr.size() - 1);
    	cout << "升序排列:"; display(arr);
    	quickSort_2(arr, 0, arr.size() - 1);
    	cout << "降序排列:"; display(arr);
    }
    
    int main()
    {
    	test();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    注意:上述升序与降序的主要区别就是程序中的大小判断条件相反!

    2.1.2 运行结果

    在这里插入图片描述

    2.2 挖坑法

    2.2.1 代码

    #include 
    #include 
    using namespace std;
    
    void display(vector<int>& arr)
    {
    	for (auto& n : arr)
    		cout << n << " ";
    	cout << endl;
    }
    // 将数组以升序进行排列!
    void quickSort2(vector<int>& arr, int left, int right) 
    {
    	if (left >= right)
    		return;
    	int key = arr[left];
    	int begin = left;
    	int end = right;
    	while (begin < end)
    	{
    		while (begin < end && arr[end] >= key)
    			--end;
    		arr[begin] = arr[end];//此处其实也可通过判断begin与end是否相等来减少多余操作
    		while (begin < end && arr[begin] <= key)
    			++begin;
    		arr[end] = arr[begin];//此处其实也可通过判断begin与end是否相等来减少多余操作
    	}
    	arr[begin] = key;
    	quickSort2(arr, left, end - 1);
    	quickSort2(arr, end + 1, right);
    }
    // 将数组以降序进行排列!
    void quickSort2_2(vector<int>& arr, int left, int right)
    {
    	if (left >= right)
    		return;
    	int key = arr[left];
    	int begin = left;
    	int end = right;
    	while (begin < end)
    	{
    		while (begin < end && arr[end] <= key)
    			--end;
    		arr[begin] = arr[end];//此处其实也可通过判断begin与end是否相等来减少多余操作
    		while (begin < end && arr[begin] >= key)
    			++begin;
    		arr[end] = arr[begin];//此处其实也可通过判断begin与end是否相等来减少多余操作
    	}
    	arr[begin] = key;
    	quickSort2_2(arr, left, begin - 1);
    	quickSort2_2(arr, begin + 1, right);
    }
    void test()
    {
    	vector<int> arr = { 6, 3, 1, 8, 7, 2, 4 };
    	cout << "原数组:"; display(arr);
    	quickSort2(arr, 0, arr.size() - 1);
    	cout << "升序排列:"; display(arr);
    	quickSort2_2(arr, 0, arr.size() - 1);
    	cout << "降序排列:"; display(arr);
    }
    
    int main()
    {
    	test();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    2.2.2 运行结果

    在这里插入图片描述

    2.3 前后指针

    2.3.1 代码

    #include 
    #include 
    using namespace std;
    
    void display(vector<int>& arr)
    {
    	for (auto& n : arr)
    		cout << n << " ";
    	cout << endl;
    }
    // 将数组以升序进行排列!
    void quickSort3(vector<int>& arr, int left, int right)
    {
    	if (left >= right)
    		return;
    	int prev = left;
    	int cur = left + 1;
    	int key = arr[left];
    	while (cur <= right)
    	{
    		if (arr[cur] < key && ++prev != cur)//小于基准值且不连续时进行交换
    			swap(arr[prev], arr[cur]);
    		++cur;
    	}
    	swap(arr[left], arr[prev]);
    	quickSort3(arr, left, prev - 1);
    	quickSort3(arr, prev + 1, right);
    }
    // 将数组以降序进行排列!
    void quickSort3_2(vector<int>& arr, int left, int right)
    {
    	if (left >= right)
    		return;
    	int prev = left;
    	int cur = left + 1;
    	int key = arr[left];
    	while (cur <= right)
    	{
    		if (arr[cur] > key && ++prev != cur)//小于基准值且不连续时进行交换
    			swap(arr[prev], arr[cur]);
    		++cur;
    	}
    	swap(arr[left], arr[prev]);
    	quickSort3_2(arr, left, prev - 1);
    	quickSort3_2(arr, prev + 1, right);
    }
    void test()
    {
    	vector<int> arr = { 6, 3, 1, 8, 7, 2, 4 };
    	cout << "原数组:"; display(arr);
    	quickSort3(arr, 0, arr.size() - 1);
    	cout << "升序排列:"; display(arr);
    	quickSort3_2(arr, 0, arr.size() - 1);
    	cout << "降序排列:"; display(arr);
    }
    
    int main()
    {
    	test();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    2.3.2 运行结果

    在这里插入图片描述
    上述三种方法,个人推荐用第二种~

  • 相关阅读:
    DevOps和CI/CD以及在微服务架构中的作用
    Natapp内网穿透
    贝叶斯分位数回归、lasso和自适应lasso贝叶斯分位数回归分析免疫球蛋白、前列腺癌数据...
    音视频开发—V4L2介绍,FFmpeg 打开摄像头输出yuv文件
    实例分割算法综述
    Tmux 简单使用
    Java学习笔记5.3.2 Set接口 - TreeSet类
    斐波那契数列二(马蹄集)
    Twincat-Simulink 出现问题总结
    QGIS开发笔记(二):Windows安装版二次开发环境搭建(上):安装OSGeo4W运行依赖其Qt的基础环境Demo
  • 原文地址:https://blog.csdn.net/m0_51961114/article/details/126647887