快速排序【递归】【非递归】

前言

打了两年的ACM,比赛中从来没用过快速排序,之前面试一直被问,于是学了一波,递归版和非递归版都有,每次面试手撕代码都因为太紧张写不好,现场思考怎么写,GG

Partition

这个是快速排序的核心,通过移动指针来进行划分。
也就是在数组中,找一个数字使得比他小的数字划分到左边,比他大的数字划分到右边,再对两边进行划分,这样不断的划分,最后数组就会变得有序,但是众所周知,快速排序是极其不稳定的,在某种极端的情况下,时间复杂度会从 O ( n l o g n ) O(nlogn) O(nlogn)变成 O ( n 2 ) O(n^2) O(n2),所以我们可以在每次划分的时候随机一个下标,将该下标位置的数,与结尾的数字互换,减少出现极端的情况的机率。
以下我对于划分函数写了两个,一个针对与单指针划分,一个是常用的双指针划分,两者都是返回排序完后基数(中间值)的下标。

递归与非递归

递归版本其实很简单,就是我们不停地划分,然后再次调用两次函数即可;
非递归版本采用了栈这个数据结构,每次将得到地区间的左右端点下标放进栈里面,类似于深度优先搜索的非递归版本的写法。

C++代码

以下是我写的版本,有错误请指出,欢迎交流


//单指针分割
int singlePartition(vector<int>& nums, int begin, int end) {
	int randIndex = rand() % (end - begin + 1) + begin;//随机标
	swap(nums[randIndex], nums[end]);//交换 随机下标 和 最右边的位置
	int index = begin;
	for(int i = begin; i < end; i++) {
		if(nums[i] <= nums[end]) {
			swap(nums[index++], nums[i]);
		}
	}
	swap(nums[index], nums[end]);
	return index;
}

int doublePartition(vector<int>& nums, int begin, int end) {
	int randIndex = rand() % (end - begin + 1) + begin;
	swap(nums[randIndex], nums[end]);
	int low = begin, high = end, pivot = nums[begin];
	while(low < high) {
		while(low < high && nums[high] >= pivot) {
			high--;
		}
		if(low < high && nums[high] < pivot) {
			swap(nums[high], nums[low]);
		}
		while(low < high && nums[low] <= pivot) {
			low++;
		}
		if(low < high && nums[high] > pivot) {
			swap(nums[high], nums[low]);
		}
	}
	nums[low] = pivot;
	return low;
}
//递归版快速排序
void recQuickSort(vector<int>& nums, int begin, int end) {
	if(begin >= end) {
		return;
	}
	int mid = doublePartition(nums, begin, end);//得到划分的位置
	recQuickSort(nums, begin, mid-1);
	recQuickSort(nums, mid+1, end);
}

void push(stack<int>& st, int l, int r) {
	st.push(l);
	st.push(l);
}

//非递归版快速排序
void unRecQuickSort(vector<int>& nums, int begin, int end) {
	stack<int> st;
	push(st, begin, end);
	while(!st.empty()) {
		int r = st.top();
		st.pop();
		int l = st.top();
		st.pop();
		if(l >= r) {
			continue;
		}
		int mid = doublePartition(nums, l, r);//得到划分的位置
		push(st, l, mid-1);
		push(st, mid+1, r);
	}
}

你可能感兴趣的:(排序算法)