快速排序是对冒泡排序的一种改进。
基本思路:
对于一维数组,先取数据中的某一个数为基数baseNum,一般为第一个。left为最左端数组的位置,right为最右端数组的位置。
1 先从右向左循环,与baseNum比较,直到遇到比baseNum小的数为止,将该数赋给baseNum所在位置。
2 从左向右循环,与baseNum比较,直到遇到比baseNum大的数为止,将该数赋给循环1中找到的那个数的位置。
3 循环1,2,直到left不小于right。再将baseNum赋给此时的left位置。
其实,以上目的只有一个,让baseNum左边的数都比它小,右边的数都比它大。
然后再递归循环,baseNum左边的数组和baseNum右边的数组。
举例:
数组: 6,4,3,7,9,2,10
取基数为数组中第一个数:6 。left:0;rithg:6
第一次循环从右向左与6对比,2是第一个小于6的数,将2赋给left所在的位置,结果 : 2,4,3,7,9,2,10 left:0;right:5
第二次循环从左向右与6对比,7是第一个大于6的数,将7赋给right所在的位置,结果: 2,4,3,7,9,7,10 left:3;right:5
第三次循环,再从right位置开始向左对比,9是第一个大于6的数,将9赋给left所在的位置,结果 : 2,4,3,9,9,7,10 left:3;right:4
些时,已到left<right的临界点,固第一轮循环完成,将baseNum赋给left所在的位置,结果: 2,4,3,6,9,7,10 left:3;right:4
这样,我们就确保了baseNum:6 左边的数都比它小,右边的数都比它大。
我们再将6左边的数组,即2,4,3和右边的数组,即9,7,10分别进行一轮这样的循环。一直这样递归循环下去,就可以将该数组按从小到大的方式排序了。
好,下面贴代码:
class Program
{
//Main函数用于测试
static void Main(string[] args)
{
List<int> list = new List<int>();
Random rand = new Random();
for (int k = 0; k < 200; k++)
{
list.Add(rand.Next(100));
}
Console.WriteLine("Before Sort");
Console.WriteLine();
foreach (int i in list)
{
Console.Write(i + " ");
}
//调用快速排序
Program.QuickSort(list, 0, list.Count - 1);
Console.WriteLine("After Sort");
foreach (int i in list)
{
Console.Write(i + " ");
}
Console.ReadLine();
}
//返回中间数所处的位置
private static int LookUpNum(List<int> list, int left, int right)
{
int baseNum = list[left];//取第一个数据为对比数据
while (left < right)
{
//第一躺,从右向左找,直到找到第一个小于baseNum的数为止
//然后将这个数赋给list[left] ,即将比较小的数放左边
while (left < right && baseNum <= list[right])
right--;
list[left] = list[right];
//第二躺,从左向右找,直到找到第一个大于baseNum的数为止
//然后将这个数赋给list[right],即将比较大的数放右边
while (left < right && list[left] <= baseNum)
left++;
list[right] = list[left];
}
//将baseNum赋给list[left],即将baseNum插入中间
list[left] = baseNum;
return left;
}
//快排,注意递归调用
private static void QuickSort(List<int> list,int left,int right)
{
if (left < right)
{
//获取中间数所处的位置
int num = LookUpNum(list, left, right);
//递归中间数右边的再排序
QuickSort(list, num + 1, right);
//递归中间数左边的再排序
QuickSort(list, left, num - 1);
}
}
}