1.概念:从待排序数组中选择一个基准值,把小于基准值的数放到基准值的左边,把大于基准值的数放在基准值的右边,最后左边和右边的数组用同样的方法递归排序。
2.实现
选的是数组第一个元素作为基准元素
/// <summary>
/// 快速排序,前后指针跟进
/// </summary>
public void QuickStart(int[] args,int start,int end)
{
//起始位置索引需要大于末尾位置索引
if (start>=end)
{
return;
}
var centerIndex = QuickStartSub1(args, start, end);//返回基准值的位置
QuickStart(args, start, centerIndex - 1);//递归左边数组
QuickStart(args, centerIndex + 1, end);//递归右边数组
}
/// <summary>
/// 前后指针跟进
/// </summary>
/// <param name="args"></param>
/// <param name="start"></param>
/// <param name="end"></param>
/// <returns></returns>
private int QuickStartSub1(int[] args, int start, int end)
{
int goal = args[start];
int i = start + 1;
for (int j = i; j <= end; j++)
{
if (args[j] <= goal)
{
var temp = args[j];
args[j] = args[i];
args[i] = temp;
i++;
}
}
args[start] = args[i - 1];
args[i - 1] = goal;
return i - 1;
}
/// <summary>
/// 快速排序,头尾指针
/// </summary>
public void QuickStart2(int[] args, int start, int end)
{
if (start >= end)
{
return;
}
var centerIndex = QuickStartSub2(args, start, end);
QuickStart(args, start, centerIndex - 1);
QuickStart(args, centerIndex + 1, end);
}
/// <summary>
///
/// </summary>
/// <param name="args"></param>
/// <param name="start"></param>
/// <param name="end"></param>
/// <returns></returns>
public int QuickStartSub2(int[] args,int start,int end)
{
int goal = args[start];
while (start < end)
{
while (start < end && args[end] >= goal)
{
end--;
}
args[start] = args[end];
while (start < end && args[start] <= goal)
{
start++;
}
args[end] = args[start];
}
args[start] = goal;
return start;
}
最坏时间复杂度:O(n^2)
平均时间复杂度:O(nlogn)=>T(n)=2*T(n/2)+O(n)
最好时间复杂度:O(nlogn)