快速排序

快速排序是实践中性能最好的排序是算法,快速排序的时间复杂度跟数据有关,最坏的情况下是O(n^2),最佳情况为O(n*lg(n))。快速排序类似于合并排序,使用了分治和递归,但是能够做到in place排序。

快速排序首先选定一个中位数,把小于这个数的元素移到左边,大于这个数的元素移到右边,最后把中位数放到中间。这个时候,这个中位数就已经排好序了。然后再对这个中位数左右两侧的子数组递归的执行快速排序,直到所有的“中位数”都排到了合适的位置,整个数组也就排好了。

 

/** 
 * @brief partition for quick sort
 * 
 * Select the last element as the Q value, elements between index p and i
 * are smaller than Q, elements between index i + 1 and r - 1 are greater than
 * or equal to Q. Swap Q with the elements in index (i + 1). return index of Q.
 *
 * @note Complexity O ( n )
 * @return Index of Q value.
 */
int partition (int *array, int p, int r)
{
	int i, j, x;
	x = array[r];
	i = p - 1;

	for (j = p; j < r; j++)
	{
		if (array[j] < x)
		{
			i++;
			swap (&array[j], &array[i]);
		}
	}

	swap (&array[i + 1], &array[r]);
	return i + 1;
}


/**
 * @brief quick sort
 *
 * Partition array into 2 sub-sequences withe middle number Q index with q,
 * so that in each recursion, Q is placed in the right place.
 * 
 * @note Complexity O ( n*lg(n) )
 */
void quick_sort (int *array, int p, int r)
{
	int q;
	if (p < r)
	{
		q = partition (array, p, r);
		quick_sort (array, p, q - 1);
		quick_sort (array, q + 1, r);
	}
}

这个算法还有两处可以优化的地方:
A)目前算法中每次选择的中位数都是数组的最后一个元素,为了获得更好的平均性能,可以选择一个随机的元素

B)使用循环消除尾递归

updatedupdated2022-02-222022-02-22