[排序算法]快速排序

参考:《漫画算法-小灰的算法之旅》

目录

1、快速排序算法的思想

2、快速排序法的流程

3、基准元素的选择

4、元素的交换(此处只介绍单边循环法)

5、快速排序代码


1、快速排序算法的思想

快速排序算法使用了分治法的思想,在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列的一边,从而把数列拆成两个部分。

2、快速排序法的流程

 每一轮的比较和交换,需要把数组全部元素都遍 历一遍,时间复杂度是O(n)。这样的遍历一共需要 多少轮呢?假如元素个数是n,那么平均情况下需要 logn轮,因此快速排序算法总体的平均时间复杂度是 O(nlogn)

3、基准元素的选择

选择基准元素最简单的方式就是选择数列的第一个元素。醉着选择在绝大多数情况下是没有问题的。但是当一个数列是逆序时,每一轮只能确定基准元素的位置。此时(最坏的情况)的时间复杂是O(n^2)。为了避免这种情况的发生,可以随机选择一个元素作为基准元素,并让基准元素和数列首元素交换位置。

4、元素的交换(此处只介绍单边循环法)

原始数列如上所示,对其从小到大进行排序。首先选定一个基准元素pivot。同时设置一个mark指针指向数列起始位置,这个mark指针代表小于基准元素的区域边界

从基准元素的下一个位置开始遍历数组,如果遍历的元素大于基准元素,就继续往后遍历。如果遍历到的元素小于基准元素,则需要做两件事:第一,把mark指针右移1位,因为小于pivot的区域边界增大了1;第二,让最新遍历到的元素和mark指针所在位置的元素交换位置,因为最新遍历的元素归属于小于pivot的区域。

5、快速排序代码

using namespace std;
#include<iostream>
#include<string>
int partition(int arr[], int startIndex, int endIndex) {
	//取第一个位置的元素作为基元素
	int pivot = arr[startIndex];
	int mark = startIndex;

	for (int i = startIndex + 1; i <= endIndex; i++) {
		if (arr[i] < pivot) {
			mark = mark + 1;
			int p = arr[mark];
			arr[mark] = arr[i];
			arr[i] = p;
		}
	}
	arr[startIndex] = arr[mark];
	arr[mark] = pivot;
	return mark;
}

void quickSort(int arr[], int startIndex, int endIndex) {
	//递归结束条件:startIndex>= endIndex
	if (startIndex >= endIndex) {
		return;
	}
	//得到基准元素的位置
	int pivotIndex = partition(arr, startIndex,endIndex);
	quickSort(arr, startIndex, pivotIndex-1);
	quickSort(arr, pivotIndex + 1, endIndex);
}

int main()
{
	int arr[] = { 4, 4, 6, 5, 3, 2, 8, 1 };
	int endIndex = sizeof(arr) / sizeof(arr[0])-1;
	quickSort(arr, 0, endIndex);
	for (int i = 0; i <= endIndex; i++) {
		cout << arr[i] << endl;
	}
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45922730/article/details/129307254