快速排序
来源:互联网 发布:access数据库心得体会 编辑:程序博客网 时间:2024/05/17 04:24
今天把快速排序写好,贴上代码,后面简单把原理讲一下
/****************************************************************
Function: sort_partion
Date: 2010-06-10
Author: Robbie
Description: 将数列分割成两部分
Input: INT *piData 待分割的数列
INT iLeft 数列最左下标
INT iRight 数列最右下标
Output: None
Return: 分割点
Modify:
*****************************************************************/
STATIC UINT sort_Partition(IN INT *piData, IN INT iLeft, IN INT iRight)
{
INT iKey = piData[iLeft]; /* 取第一个数为分割界限值 */
while (iLeft < iRight)
{
while ((piData[iRight] >= iKey) && (iLeft < iRight))
{
iRight--;
}
piData[iLeft] = piData[iRight]; /* 将数据小于界限值的移到左边 */
while ((piData[iLeft] <= iKey) && (iLeft < iRight))
{
iLeft++;
}
piData[iRight] = piData[iLeft]; /* 将数据大于界限值的移到右边 */
}
piData[iLeft] = iKey; /* 界限值最后的位置 */
return iLeft;
}
/****************************************************************
Function: sort_Quick
Date: 2010-06-10
Author: Robbie
Description: 递归分割
Input: INT *piData 待排序的数列
INT iLeft 数列最左下标
INT iRight 数列最右下标
Output: None
Return: None
Modify:
*****************************************************************/
STATIC VOID sort_Quick(IN INT *piData, IN INT iLeft, IN INT iRight)
{
INT iKey;
if (iLeft < iRight)
{
iKey = sort_Partition(piData, iLeft, iRight); /* 将数列一分为二 */
sort_Quick(piData, iLeft, iKey - 1); /* 对上半部分数列递归排序 */
sort_Quick(piData, iKey + 1, iRight); /* 对下半部分数列递归排序 */
}
}
/****************************************************************
Function: SORT_Quick
Date: 2010-06-10
Author: Robbie
Description: 快速排序
Input: INT *piData 待排序的数列
UINT uiNum 数列个数
Output: None
Return: None
Modify:
*****************************************************************/
VOID SORT_Quick(IN INT *piData, IN UINT uiNum)
{
if ((uiNum <= 1) || (NULL == piData)) /* 一个数或没有数据退出 */
{
return;
}
sort_Quick(piData, 0, (INT)(uiNum - 1));
}
快速排序是对冒泡排序的一种改进,它的基本思想是通过一趟排序将待排纪录分割成独立两部分,其中一部分数均比另外一半小,则可分别对这两部分数据继续进行排序,已达到整个序列有序。可采用递归方法。
第一趟排序:
初始: 49 38 65 97 76 13 27 49
left right 初始以49为分割界限(一般选第一个数为分割界限)
第一次交换后: 27 38 65 97 76 13 49
left right
第二次交换后: 27 38 97 76 13 65 49
left right
第三次交换后: 27 38 13 97 76 65 49
left right
第四次交换后: 27 38 13 76 97 65 49
left right
第五次: 27 38 13 76 97 65 49
left
right
这时第一趟排序退出,可以看出比49大的数据都在右边,比49小的数据都在左边,原来数列分割成两部分了,
接下来分别对两个子数列进行分割:
第二趟排序
27 38 13 此子数列以27为分割界限,进行分割,类似上面
76 97 65 49 此子数列以76为分割界限,进行分割,类似上面
第二趟排序结束后,每个子数列又将分别分割成两个子数列,依次递归,直至无法分割
这样整个数列排序完成。
快速排序是一种不稳定排序,如序列为 5 3 3 4 3 8 9 10 11, 现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱。(嘿嘿,什么是不稳定排序?非常通俗的讲,在排序前后,相等的两个数的位置顺序不变,这里第5个元素3,原来是是在前面两个3后面,排序后在两个3前面了,因为位置顺序变了,懂了吧,是不是很简单。。。)
快速排序的平均时间为knlnn,n为待排序个数,k为某个常数,经验证明,在所有同数量级排序方法中,快速排序的常数因子k最小,具体为什么,我也懒得推导了。。。偶也不会。因此,就平均时间而言,快速排序是目前被认为最好的一种内部排序方法。