快速排序算法,切分函数勘误,错误源自《算法 第4版》,当待排序列无重复元素时,该错误不会显现,但是当出现重复元素时,有可能会出现死循环。
向下不满足数据和向上不满足数据,在交换位置后,应该对索引进行更新;否则由于重复元素的存在,交换的数据和枢轴数据相同,交换后,两边数据依旧不满足,索引不会更新,将会陷入死循环。
一、快速排序原理
快速排序最为重要的操作是切分(partition),以升序为例,切分操作实现的方法是,根据待排序列中的一个选定值(该值的选取有很多种方法,当然也可以随便选取,选择的不同方式并不会影响算法的功能,只是会影响算法的平均速度),将待排序列中小于选定值的值放在选定值的左侧,大于选定值的值放在右侧。
算法顺序:
1、调用切分,将待排序列切割成,比选定值小的值组成的序列和比选定值大的值组成的序列(针对重复值,待会观察)
2、以上述步骤中产生的两个序列为处理对象,回到步骤1
二、代码实现
#include<iostream>
using namespace std;
void swap(int &a, int &b) //交换两个值
{
int temp;
temp = a;
a = b;
b = temp;
}
int partition(int a[], int lo, int hi) //切分函数的实现
{
int v = a[lo];
int i = lo + 1;
int j = hi;
while (true)
{
while (a[i]<v)
{
if (i<hi) i++;
else break;
}
while (v<a[j])
{
if (j>lo) j--;
else break;
}
if (i >= j) break; //注意跳出条件
swap(a[i], a[j]);
i++; //更新操作
j--; //更新操作
}
swap(a[lo], a[j]); //这一步是将切分所依据的选定值放到序列中合适的位置
return j;
}
void sort(int a[], int lo, int hi)
{
if (lo >= hi)
{
return;
}
int index = partition(a, lo, hi);
sort(a, lo, index - 1);
sort(a, index + 1, hi);
}
int main()
{
int num[6] = { 3, 5, 2, 6, 1, 7 };
cout << "排序前: " << num[0] << " " << num[1] << " " << num[2] << " " << num[3] << " " << num[4] << " " << num[5] << endl;
sort(num, 0, 5);
cout << "排序后: " << num[0] << " " << num[1] << " " << num[2] << " " << num[3] << " " << num[4] << " " << num[5] << endl;
system("pause");
return 0;
}
结果: