排序算法实践编程之——快排法


QuickSort.h文件:

#include <iostream>
#include <string>

class QuickSort
{
public:
	QuickSort();
	~QuickSort();
	void QuickSort::swap(int arr[], int i, int j);
	void QuickSort::partitionQS(int arr[], int left, int right);
	void QuickSort::quickSort(int arr[],int n);
	
private:

};
修改前,存在问题的QuickSort.cpp文件:

#include <iostream>
#include <string>
#include "QuickSort.h"
using namespace std;

QuickSort::QuickSort()
{
}

QuickSort::~QuickSort()
{
}

void QuickSort::swap(int arr[],int i,int j)
{
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
	return;
}

void QuickSort::quickSort(int arr[],int n)
{

	// 原子级逻辑   这种逻辑的结果是:最终左侧的数据都比中间小,右侧的数据都比中间大。  因此,可以通过二分法,递归调用。
  /*
    size_t i = 0;
	size_t j = n;
    for (; i < j && arr[i] > arr[0]; ++i);
	for (; j > i && arr[j] < arr[0]; --j);
	swap(arr, i, j);
	if (arr[i]==arr[j] && arr[i]<arr[0])
	{
		swap(arr, 0, i);
	} */

	partitionQS(arr, 0, n-1);

	return;

}

void QuickSort::partitionQS(int arr[],int left,int right)
{
	rsize_t i = left;
	rsize_t j = right;
	if (left>=right)
	{
		return;
	}
	else
	{
		while (i<j)
		{
			for (; j > i && arr[j] > arr[left]; --j);      //注意,以左侧为基数,需要右侧指针先扫描,最终才会相遇在小于基数的中间位置
			for (++i; i < j && arr[i] < arr[left]; ++i);
			swap(arr, i, j);
		}

		if (arr[i] == arr[j] )
		{
			if (arr[i]<arr[left])
			{
				swap(arr, left, i);
			}
			partitionQS(arr,left,i);
			partitionQS(arr, i, right);
		}
	}

}

main.cpp文件:

#include <iostream>
#include <string>
#include "BubbleSort.h"
#include "SelectSort.h"
#include "InsertSort.h"
#include "QuickSort.h"

using namespace std;
void main(int arc, char ** argv)
{
	const int ArSize = 20;
	int arr[ArSize] = {6, 2, 8, 5, 1, 4 ,23,12,13,10,54,16,36,32,65,17,64,33,3,21};
	//for (size_t i = 0; i < ArSize; i++)
	//{ 
	//	cin >> arr[i];
	//}

	cout << "arr: ";
	for (size_t i = 0; i < ArSize; i++)
	{
		cout << " " << arr[i];
	}
	cout << endl;
	//BubbleSort bs;
	//bs.bubbleSort(arr,ArSize);
	
	//SelectSort ss;
	//ss.selectSort(arr,ArSize);

	//InsertSort is;
	//is.insertSort(arr,ArSize);

	QuickSort qs;
	qs.quickSort(arr,ArSize);

	cout << "sorted value: " << endl;

	cout << "arr: ";
	for (size_t i = 0; i < ArSize; i++)
	{
		cout << " " << arr[i] ;
	}
	cout << endl;
	//cin.get();
	cin.get();
	return;

}


运行结果存在问题。

对代码进行修改 :

QuickSort.cpp 文件如下 : 

#include <iostream>
#include <string>
#include "QuickSort.h"
using namespace std;

QuickSort::QuickSort()
{
}

QuickSort::~QuickSort()
{
}


void QuickSort::prtArr(int arr[], const int ArSize)
{
	cout << "arr: ";
	for (size_t i = 0; i < ArSize; i++)
	{
		cout << " " << arr[i];
	}
	cout << endl;
	return;
}

void QuickSort::swap(int arr[],int i,int j)
{
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
	return;
}



void QuickSort::quickSort(int arr[],int n)
{

	// 原子级逻辑   这种逻辑的结果是:最终左侧的数据都比中间小,右侧的数据都比中间大。  因此,可以通过二分法,递归调用。
  /*
    size_t i = 0;
	size_t j = n;
    for (; i < j && arr[i] > arr[0]; ++i);
	for (; j > i && arr[j] < arr[0]; --j);
	swap(arr, i, j);
	if (arr[i]==arr[j] && arr[i]<arr[0])
	{
		swap(arr, 0, i);
	} */
	quicksort(arr, 0, n-1);
	return;
}

int QuickSort::partitionQS(int arr[],int left,int right)
{
	int pivotPos = left;
	int pivotKey = arr[left];
	while (left<right)
	{
		for (; right > left && arr[right] >= pivotKey; --right);      //注意,以左侧为基数,需要右侧指针先扫描,最终才会相遇在小于基数的中间位置
		for (; left < right && arr[left] <= pivotKey; ++left);
		if (left<right)
		swap(arr, left, right);
	}
	swap(arr, pivotPos,left);
	return left;
}

void QuickSort::quicksort(int arr[], int left, int right)
{
	if (left >= right)   // 边界条件
		return;
	prtArr(arr, 20);
	int pivotPos = partitionQS(arr,left,right); // 单次划分
	quicksort(arr, left, pivotPos-1);     //左递归 调用
	quicksort(arr, pivotPos+1, right);    //右递归 调用

}

1、将单次的划分流程单独封装在一个函数里面,  功能是:输入两端值, 从两端向中间扫描,交换数值,直到指针相遇,交换基准值 并 输出中间值。

2、递归函数内部:

1)明确边界, left>=right

2)调用单次划分

3)递归

运行的过程及结果如下:




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值