• 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 运行结果

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

  • 相关阅读:
    win10 Ubuntu 子系统下编译ffmpeg 和 x264
    算法竞赛入门【码蹄集新手村600题】(MT1351-1400)
    RPC 核心原理理论分析
    edu 156 div2 c
    Kubernetes(k8s)的Pod控制器Job和CronJob详细讲解
    Redis-01基本数据结构
    【牛客网-前端笔试题】——Javascript专项练习5
    这些Java面试题,有点虐人!
    UVM中uvm_config_db非直线的设置与获取
    SSD202 Linux开发日志记录
  • 原文地址:https://blog.csdn.net/m0_51961114/article/details/126647887