【排序总结】快排

快速排序是最常用的排序算法,基本思想是分治。随机找一个分割数,把比他小的数放他左边,比他大的数放他右边。对左边的数和右边的数再分别重复以上操作。

void qsort(int* arr, int low, int high) {
	if (low < high) {
		int pivot = partition(arr, low, high);  //用中心点将数组划分为两部分,并返回划分后中心点的位置
		qsort(arr, low, pivot - 1);		//递归排序左子数组
		qsort(arr, pivot + 1, high);		//递归排序右子数组
	}
}


其中,划分函数partition是关键。该函数有两个作用,首先是根据中心点对数组进行粗糙的排序,即小数去左大数去右”;其次是返回排序后中心点的位置,便于下一步递归

划分函数的核心思想是用low和high两个指针来标记扫描的位置,low从左向右进行扫描,找比key大的数并和high所在的数进行交换(仅交换数值,指针未变),high从右向左进行扫描,找key小的数并和low进行交换,以此类推交替进行。记住:low和low左边的数都是比中心点小或等的数,代表已经排好的部分,不需要再动。high和high右边的数同理。扫描和交换过程只针对两指针中间的这一部分,直至两指针重合。

int partition(int* arr, int low, int high) {
	int pivot = arr[low];     //取中心点(可以是端点,也可以是中间位置的某点)
	while (low<high) {
		while (low<high && arr[high] >= pivot) --high;  //从右向左扫描,遇到比中心点小的值时停止
		arr[low] = arr[high];
		arr[high] = pivot;				//将小值和中心点进行交换
		while (low<high && arr[low] <= pivot) ++low;    //从左向右扫描,遇到比中心点大的值时停止
		arr[high] = arr[low]; 
		arr[low] = pivot;				//将大值和中心点进行交换
	}
	//扫描完成,中心点位置确定并返回
	arr[low] = pivot;
	return low;
}
因为是取arr[low]为中心点,所以最开始时是从右往左扫描,找到小值与low下标对应的中心点进行交换。交换后,中心点到了high下标里,再从左往右扫描。。。循环直至两下标碰面,它们共同指向的还是中心点。也就是说,自始至终,都是中心点和它们交换,知道把中心点送到正确的位置。





猜你喜欢

转载自blog.csdn.net/sinat_38972110/article/details/80093820