快速排序
1、基本思想:
a)得到一个无序的长度为11的数组
b)
1)取数组中最大元素,并与末尾元素交换,即12与10进行交换;
2)选取位于数组中间位置(忽略末尾元素,因为末尾元素的位置已对)的元素作为边界值,并与数组首位的元素进行交换,即 6与8进行交换。
3)定义lower与upper索引,指向除去边界以及最大值的其余元素的首尾。
c)
1)lower指向的元素值若小于边界值,则lower++,否则进入2),这保证了在lower左边的数值都小于边界值。因此这也说明了 为什么我们要进行b.1步骤,防止取到的边界值是最大值,则此时lower不断++,超出索引范围。
2)upper指向的元素值若大于边界值,则uprer++,否则进入3),这保证了在upper右边的数值都小于边界值。
3)交换lower与upper的元素。继续执行1)。
d)
1)当lower>upper时,说明此时upper已经到达了边界值在数组的正确位置,即upper的左边元素都小于边界值,右边都大于元 素值。
2)此后把边界值的左、右边当成两个子数组继续执行如上操作,即递归。
2、复杂度:
3、源代码:
#include <iostream>
using namespace std;
template<class T>
int max_arr_index(T data[], int n)
{
int max_index = 0;
T max = data[0];
for (int i = 1;i < n;++i)
if (data[i] > max) {
max = data[i];
max_index = i;
}
return max_index;
}
template<class T>
void quicksort(T data[], int first, int last)
{
int lower = first + 1, upper = last;
//取中间元素为边界值,并与子数组的首元素交换
swap(data[first], data[(first + last) / 2]);
T bound = data[first];
while (lower <= upper) {
while (data[lower] < bound)
lower++;
while (data[upper] > bound)
upper--;
if (lower < upper)
swap(data[lower++], data[upper--]);
else
//确保lower最终>upper
lower++;
}
swap(data[first], data[upper]);
//由于upper为边界值的位置,因为判定的时候以upper为准
if (first < upper - 1)
//子数组进行递归
quicksort(data, first, upper - 1);
if (upper + 1 < last)
quicksort(data, upper + 1, last);
}
template<class T>
void printdata(T data[], int n)
{
for (int i = 0;i < n;++i)
cout << data[i] << " ";
}
int main()
{
//随机生成不相等的100个数
int data[100];
int n = 100;
for (int i = 0; i <= n-1; ++i)
data[i] = i;
for (int i = n-1; i >0; --i)
swap(data[i], data[rand() % i]);
//将数组中元素最大值与数组末尾值交换
swap(data[n - 1], data[max_arr_index(data, n)]);
//快速排序
quicksort(data, 0, n - 2);
printdata(data, n);
system("pause");
return 0;
}