在这里先跟各位说一声抱歉,我之前的博客出现了错误,先补发一篇予以纠正,本人能力有限,之前给大家造成的误解烦请大家原谅!
快速排序,是公认的排序最优解,就连sort函数也是快排的封装!
算法思想:
1、先选取一个基准点,和两个指针i,j。通常基准点就是排序数组的第一个数。
2、j指针先出发,从右至左寻找比基准点小的数,随后i出发,从左至右寻找比基准点大的数,交换两个指针的位置,以达到让小于基准点的数在左边,大于基准点的数在右边的效果。直到两指针相等(i == j)时停止循环查找。
3,交换基准点和arr[i]此时( i == j)让基准点居中,递归排序左半部分和右半部分。排序完成。
这里选取leetcode的一个题目来验证我的算法。
结果如下:
代码中需要注意的问题很多:
请看注释:
//快速排序
void quick(vector<int>& arr, int begin, int end,int len)
{
if (begin < 0 || end < 0 || begin >= len || end >= len || begin > end)
{
return;
}
//首先是选取基准点,我们这里选择arr[begin]为基准点
int i = begin;
int j = end;
while (i != j)
{
//j先出发
//注意:相等的情况也要加上,因为可能会出现arr[j] == arr[begin]的情况
while (arr[j] >= arr[begin] && i < j) //每次都跟基准点比较
{ //目的是让比基准点小的在左边,大的在右边
j--;
}
while (arr[i] <= arr[begin] && i < j)
{
i++;
}
//如果两个指针不在同一个位置的话就交换两个指针的位置
if (j > i)
{
swap(arr[i], arr[j]);
}
}
//然后把基准点移到中间去,此时j, i已经相等
swap(arr[begin], arr[i]);
//递归排序左边和右边
quick(arr, begin, i - 1, len); //不用管中间的了
quick(arr, i + 1, end,len);
}
int main()
{
vector<int>arr;
/*for (int i = 0; i < 5; i++)
{
int a = 0;
cin >> a;
arr.push_back(a);
}*/
int a = 0;
while (~scanf("%d", &a))
{
arr.push_back(a);
}
int len = arr.size();
quick(arr, 0, len - 1, len);
/*for (int i = 0; i < len; i++)
{
cout << arr[i] << " ";
}*/
cout << arr[0];
return 0;
}
如果您的代码能够通过如下测试用例,则应该没什么问题了:
输入:1 3 2 5 6
输出:1 2 3 5 6
输入:1 3 5 7 9
输出:1 3 5 7 9
输入:1 2 1
输出:1 1 2
输入:10 9 8 7 6 5 4 3 2 1
输出:1 2 3 4 5 6 7 8 9 10
输入:1 1 1 1 1
输出:1 1 1 1 1
希望和诸君共勉。