算法研究之快速排序

简介:    1 快速排序的思想       通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。


   1 快速排序的思想

      通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 

      快速排序的思想就是通过分治策略,每次对两部分的数据进行递归排序。假设我们要排序的数组是arr,从left~right这一段,我们每次选择arr[(left+right)>>1]作为基准数字(很多地方是选择第一个或者最后一个),然后把这个子段分成两部分,再进行递归

      代码:

int partition(int *arr, int l, int r){
	int pos = (l+r)>>1;//选择中间的数作为基准
	swap(arr[pos], arr[r]);//把这个数交换到最后一个位置
	int leftSeqNum = l; //左子序列的结束位置

	for(int i = l; i < r; i++){
		if(arr[i] < arr[r]){
		   if(leftSeqNum < i)
			   swap(arr[leftSeqNum], arr[i]);
		   leftSeqNum++;
		}	
	}
	//再把基准的值交换到正确的位置
	swap(arr[leftSeqNum], arr[r]);
	return leftSeqNum;
}
void quickSort(int *arr, int l, int r){
    if(arr == NULL || l == r)
		return;
	int index = partition(arr, l, r);
	if(l < index)
		quickSort(arr, l, index-1);
	if(index < r)
		quickSort(arr, index+1, r);
}

    2 假设我们要排序一个数组arr[7] = {5, 1, 3, -1, 0, 7, 4}

      第一趟:我们排序的是left = 0,right = 6,我们的基准数字是standard = arr[3] = -1,i = 0, j = 6

                   从i开始判断有没有连续小于standard的,得到 i = 0

                   从j往下判断有没有连续大于standard的,得到 j = 3

                   于是交换 arr[i] 和 arr[j],并把i++和j--,得到i = 1, j = 2,序列为-1 1 3 5 0 7 4


                   然后重复上面的,得到i = 1,j =0,于是这一轮的排序结束,最终序列为

                   -11 3 5 0 7 4,分成了两部分 ,于是对着两部分进行递归排序

         

      第二趟:我们考虑序列 1 3 5 0 7 4,left = 1,right = 6,i = 1,j = 6,standard = 5                 

                              从i开始判断有没有连续小于standard的,得到 i = 3

                   从j往下判断有没有连续大于standard的,得到 j = 6

                   于是交换 arr[i] 和 arr[j],并把i++和j--,得到i = 4, j = 5,序列为1 3 4 0 7 5

                    

                   然后重复上面的,得到i = 5,j =4,于是这一轮的排序结束,最终序列为

                   1 3 4 07 5,分成了两部分,于是对这剩下的进行递归排序

         

      第三趟: 我们考虑序列 1 3 4 0,left = 1,right = 4,i = 1,j = 4,standard = 3

                   从i开始判断有没有连续小于standard的,得到 i = 2

                   从j往下判断有没有连续大于standard的,得到 j = 4

                   于是交换 arr[i] 和 arr[j],并把i++和j--,得到i = 3, j = 3,序列为1 0 4 3

                   这边就是为什么我们需要写成while(i <= j),而不是while(i < j)的原因了,这个时候i和j指向同一个元素,我们                      还没有分成两部分


                   然后重复上面的,得到i = 4,j =3,于是这一轮的排序结束,最终序列为

                   1 04 3,分成了两部分,于是对这剩下的进行递归排序

 

        第四趟:  我们考虑序列 1 0,left = 1,right = 4,i = 1,j = 2,standard = 1

                   从i开始判断有没有连续小于standard的,得到 i = 1

                   从j往下判断有没有连续大于standard的,得到 j = 2

                   于是交换 arr[i] 和 arr[j],并把i++和j--,得到i = 1, j = 1,序列为0 1


                   这个时候序列分成了两部分,分别只有一个数字,所以继续递归向下


     注意:   为什么,在while里面的交换,那边要写成if(i <= j) swap(arr[i++], arr[j--]),大家试着想下面的一个例子

                 假设我们要排序的数组是arr[] = {1, 2, 3, 4, 5, 6, 7}

                 那么我们第一轮过后最终得到i = 3,j = 3,如果我们写成if(i < j) swap(arr[i++], arr[j--]),那么将永远执行while

                 循环,所以说为了防止这个特例的发生,必须要写成if(i <= j) swap(arr[i++], arr[j--])


     剩下的和上面差不多,大家可以试着手动写一下。快速排序很重要,希望文章能够帮助大家,谢谢!



     ==================================

     ==      from:陈国林                                        ==

     ==      email:cgl1079743846@gmail.com     ==

     ==      转载请注明出处,谢谢!                        ==

     ==================================


目录
相关文章
|
6天前
|
编解码 监控 算法
图像和视频处理中DSP算法的研究与发展
图像和视频处理中DSP算法的研究与发展
32 2
|
6天前
|
算法 前端开发
前端算法之快速排序
前端算法之快速排序
14 0
|
6天前
|
算法 调度
【问题探讨】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究
【问题探讨】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究
|
6天前
|
算法 Serverless 调度
基于分布式ADMM算法的考虑碳排放交易的电力系统优化调度研究(matlab代码)
基于分布式ADMM算法的考虑碳排放交易的电力系统优化调度研究(matlab代码)
|
6天前
|
算法 搜索推荐
R语言混合SVD模型IBCF协同过滤推荐算法研究——以母婴购物平台为例
R语言混合SVD模型IBCF协同过滤推荐算法研究——以母婴购物平台为例
|
6天前
|
机器学习/深度学习 自然语言处理 算法
【大模型】关于减轻 LLM 训练数据和算法中偏差的研究
【5月更文挑战第6天】【大模型】关于减轻 LLM 训练数据和算法中偏差的研究
|
6天前
|
机器学习/深度学习 数据采集 SQL
R语言K-Means(K均值聚类)和层次聚类算法对微博用户特征数据研究
R语言K-Means(K均值聚类)和层次聚类算法对微博用户特征数据研究
|
6天前
|
搜索推荐 算法 大数据
C排序算法研究
C排序算法研究
7 2
|
6天前
|
搜索推荐 算法 Java
快速排序------一种优雅的排序算法
快速排序------一种优雅的排序算法
|
6天前
|
数据采集 算法 数据可视化
MATLAB、R用改进Fuzzy C-means模糊C均值聚类算法的微博用户特征调研数据聚类研究
MATLAB、R用改进Fuzzy C-means模糊C均值聚类算法的微博用户特征调研数据聚类研究