快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
比如序列如下:
int[] array = {0,49,38,65,97,76,13,27,49 };
【0】下标作为暂时存储关键key的位置
选取一个数据作为关键key,最初默认就是数组的第一个数字,比如49.
设置low和high,下标位置和上标位置。最初默认low就是1,high就是数组的长度,也就是最后一位。
排序思路就是,从high向前数,找到第一个比关键key小的数子,然后拍到low的位置去
从low向后找,找到第一个比关键key大的数字,排到high的位置。
前提条件一直是low < high。
在第一趟排序的过程中,key一直49.作为一个中间暂时变量,序列数组的数据交换不影响key的变化。直到第一趟结束的时候,把key赋值给当前low所在的位置。
直到第二趟排序开始,key才会变化
第一趟排序完成以后,原来的数组就分割成为两部分,一部分是比49小的,一部分是比49大的,如图示:
{27,38,13} ,49,{76,97,65,49}。
第一趟以后 关键字已经变得下标为3的位置了(49),
然后开始第二趟排序,分表对A = {27,38,13} 和 B ={76,97,65,49} 两个分隔序列重复进行第一趟排序
规则是和第一趟排序是一致的。也是A或者B的第一个作为关键key,从low和high重复进行第一趟排序。
**当然A和B并不是真正的分隔成为两个数组,只是可以从下标来分别计算两组,比如A的范围就是low=1和high=3
B的范围就是low=5和high=8.
**其实分隔数组的范围就是第一趟结束以后 low的位置。以low为分界线,分隔了两个不同的序列。
**所以快速排序是一个递归的算法
c#代码示例如下:
#region 快速排序
/// <summary>
/// 一次普通的排序,返回该趟结束以后low的位置,low分割了数组。以low为界限
/// 查找分割后数组后的范围
/// </summary>
/// <param name="array"></param>
/// <param name="low">下标</param>
/// <param name="high">上标</param>
/// <returns></returns>
static int Partition(ref int[] array, int low, int high)
{
array[0] = array[low];//下标0为了暂时存储关键key的值
int key = array[low];//一般默认关键key就是数组的第一位
while (low < high)
{
while (low < high && array[high] >= key) --high;//从high开始找到第一个比key小的数子,
array[low] = array[high];//如果找到就交换
while (low < high && array[low] <= key) ++low;//从low开始找到第一个比key大的数字
array[high] = array[low];//找到就交换
}
array[low] = key;//退出循环以后,low的位置用原来的key填充
return low;
}
/// <summary>
/// 递推
/// </summary>
/// <param name="array"></param>
/// <param name="low"></param>
/// <param name="high"></param>
static void QSort(ref int[] array, int low, int high)
{
if (low < high)
{
int key = Partition(ref array, low, high);
QSort(ref array, low, key - 1);//分割数组以后,对低子表进行递归,
QSort(ref array, key + 1, high);//对高子表进行递归
}
}
/// <summary>
/// 开始排序
/// </summary>
/// <param name="array"></param>
static void QuickSort(ref int[] array)
{
QSort(ref array, 1, array.Length - 1);
}
#endregion
调用
int[] array = {0,49,38,65,97,76,13,27,49 };
QuickSort(ref array);
for (int n = 0; n < array.Length; n++)
{
Console.Write(array[n].ToString() + ",");
}
比如序列如下:
int[] array = {0,49,38,65,97,76,13,27,49 };
【0】下标作为暂时存储关键key的位置
选取一个数据作为关键key,最初默认就是数组的第一个数字,比如49.
设置low和high,下标位置和上标位置。最初默认low就是1,high就是数组的长度,也就是最后一位。
排序思路就是,从high向前数,找到第一个比关键key小的数子,然后拍到low的位置去
从low向后找,找到第一个比关键key大的数字,排到high的位置。
前提条件一直是low < high。
在第一趟排序的过程中,key一直49.作为一个中间暂时变量,序列数组的数据交换不影响key的变化。直到第一趟结束的时候,把key赋值给当前low所在的位置。
直到第二趟排序开始,key才会变化
第一趟排序完成以后,原来的数组就分割成为两部分,一部分是比49小的,一部分是比49大的,如图示:
{27,38,13} ,49,{76,97,65,49}。
第一趟以后 关键字已经变得下标为3的位置了(49),
然后开始第二趟排序,分表对A = {27,38,13} 和 B ={76,97,65,49} 两个分隔序列重复进行第一趟排序
规则是和第一趟排序是一致的。也是A或者B的第一个作为关键key,从low和high重复进行第一趟排序。
**当然A和B并不是真正的分隔成为两个数组,只是可以从下标来分别计算两组,比如A的范围就是low=1和high=3
B的范围就是low=5和high=8.
**其实分隔数组的范围就是第一趟结束以后 low的位置。以low为分界线,分隔了两个不同的序列。
**所以快速排序是一个递归的算法
c#代码示例如下:
#region 快速排序
/// <summary>
/// 一次普通的排序,返回该趟结束以后low的位置,low分割了数组。以low为界限
/// 查找分割后数组后的范围
/// </summary>
/// <param name="array"></param>
/// <param name="low">下标</param>
/// <param name="high">上标</param>
/// <returns></returns>
static int Partition(ref int[] array, int low, int high)
{
array[0] = array[low];//下标0为了暂时存储关键key的值
int key = array[low];//一般默认关键key就是数组的第一位
while (low < high)
{
while (low < high && array[high] >= key) --high;//从high开始找到第一个比key小的数子,
array[low] = array[high];//如果找到就交换
while (low < high && array[low] <= key) ++low;//从low开始找到第一个比key大的数字
array[high] = array[low];//找到就交换
}
array[low] = key;//退出循环以后,low的位置用原来的key填充
return low;
}
/// <summary>
/// 递推
/// </summary>
/// <param name="array"></param>
/// <param name="low"></param>
/// <param name="high"></param>
static void QSort(ref int[] array, int low, int high)
{
if (low < high)
{
int key = Partition(ref array, low, high);
QSort(ref array, low, key - 1);//分割数组以后,对低子表进行递归,
QSort(ref array, key + 1, high);//对高子表进行递归
}
}
/// <summary>
/// 开始排序
/// </summary>
/// <param name="array"></param>
static void QuickSort(ref int[] array)
{
QSort(ref array, 1, array.Length - 1);
}
#endregion
调用
int[] array = {0,49,38,65,97,76,13,27,49 };
QuickSort(ref array);
for (int n = 0; n < array.Length; n++)
{
Console.Write(array[n].ToString() + ",");
}
本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。