随机化思想的引入
在数据结构这门课程的学习中,我们了解到一种名为快速排序的算法,该算法时间复杂度为 O ( n log 2 n ) O(n\log_2 n) O(nlog2n),但是,在课程中,书本和老师都指出了它的一个缺点:在数据有序时的时间复杂度为 O ( n 2 ) O(n^2) O(n2)
为了“消除”这个缺点,随机化的思想被引入到快排中:由于数据有序,可以随机选取其中一个数将其与其他数交换,使有序的情况被破坏,从而使原有序数据的排序效率加快。
普通快排的实现
-
基本思想:
将数据划分为两部分,左边的所有元素都小于右边的所有元素;然后,对左右两边进行快速排序。 -
划分方法:
选定一个参考点(中间元素),所有元素与之相比较,小的放左边,大的放右边。 -
具体划分方法:
选择第一个元素作为中间元素。
划分:
(1)先保存该元素的值到其它位置,腾出其空间。
(2)从后往前搜索一个比中间数小的元素,并将其放置到前面的这个空位上。
(3)从前往后搜索一个比中间数大的元素,并将其放置到后面的这个位置上。
重复(2),(3),直到两边搜索的空位重合,此时将中间元素放在该空位中。
template<typename T>
void quick_sort(T array[], int left, int right)
{
if (left >= right) return;
int i = left, j = right;
T temp = array[left];
while (i != j)
{
while (array[j] > temp&&j > i) j--;
if (i < j) array[i++] = array[j];
while (array[i] < temp&&i < j) i++;
if (i < j) array[j--] = array[i];
}
array[i] = temp;
quick_sort(array, i + 1, right);
quick_sort(array, left, i - 1);
}
随机化快排的实现
随机化快排只是比普通快排增加了一个步骤:首先随机选取一个元素,与数据群首部元素交换,接下来进行快排
template<typename T>
void random_quick_sort(T array[], int left, int right)
{
srand(time(0));
if (left >= right) return;
int i = left, j = right, move = rand() % (right - left + 1) + left;
T temp = array[move];
array[move] = array[left];
while (i != j)
{
while (array[j] > temp&&j > i) j--;
if (i < j) array[i++] = array[j];
while (array[i] < temp&&i < j) i++;
if (i < j) array[j--] = array[i];
}
array[i] = temp;
random_quick_sort(array, i + 1, right);
random_quick_sort(array, left, i - 1);
}