快速排序
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 3813 此子数列以27为分割界限,进行分割,类似上面
76 9765 49 此子数列以76为分割界限,进行分割,类似上面
第二趟排序结束后,每个子数列又将分别分割成两个子数列,依次递归,直至无法分割
这样整个数列排序完成。
快速排序是一种不稳定排序,如序列为 5 3 3 4 3 8 9 10 11,现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱。(嘿嘿,什么是不稳定排序?非常通俗的讲,在排序前后,相等的两个数的位置顺序不变,这里第5个元素3,原来是是在前面两个3后面,排序后在两个3前面了,因为位置顺序变了,懂了吧,是不是很简单。。。)
快速排序的平均时间为knlnn,n为待排序个数,k为某个常数,经验证明,在所有同数量级排序方法中,快速排序的常数因子k最小,具体为什么,我也懒得推导了。。。偶也不会。因此,就平均时间而言,快速排序是目前被认为最好的一种内部排序方法。
插入排序
标签: insertoutputfunctioninputdate2010
2010-06-10 22:54 269人阅读 评论(1) 收藏 举报
分类:
Algorithms(4)
版权声明:本文为博主原创文章,未经博主允许不得转载。
今天复习了一下插入排序,先把代码贴上,后面把原理讲一下
/****************************************************************
Function: SORT_Insert
Date: 2010-06-10
Author: Robbie
Description: 插入排序
Input: INT *piData 待排序的数列
UINT uiNum 数列个数
Output:
Return:
Modify:
*****************************************************************/
VOID SORT_Insert(IN INT *piData, IN UINT uiNum)
{
INT i, j;
INT iTmp;
for (i = 1; i < uiNum; i++)
{
iTmp = piData[i]; /* 第i个数前面是有序的 */
for (j = (i - 1); (j >= 0)&& (piData[j] > iTmp); j--)
{
piData[j +1] = piData[j];
}
piData[j + 1] = iTmp;
}
}
插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的
选择排序
标签: outputfunctioninputdate算法2010
2010-06-08 23:45 230人阅读 评论(2) 收藏 举报
版权声明:本文为博主原创文章,未经博主允许不得转载。
选择是不稳定的排序。
贴上代码:
/****************************************************************
Function: SORT_Select
Date: 2010-06-07
Author: Robbie
Description: 选择算法
Input: INT *piData 待排序的数列
Output: UINT uiNum 数列个数
Return:
Modify:
*****************************************************************/
VOID SORT_Select(IN INT *piData, IN UINT uiNum)
{
INT i, j;
UINT uiMin = 0; /* 纪录最小数下标 */
INT iTmp = 0;
for (i = 0; i < (uiNum - 1); i++)
{
uiMin = i; /* 假设当前下标为i的数最小,比较后再调整 */
for (j = (i + 1); j < uiNum; j++)
{
if(piData[j] < piData[uiMin])
{
uiMin = j; /* 纪录下标 */
}
}
if (uiMin != i) /* 如果min在循环中改变,则交换数据 */
{
iTmp =piData[i];
piData[i] =piData[uiMin];
piData[uiMin]= iTmp;
}
}
}
选择排序和冒泡排序思路上有一点相似,都是先确定最小元素,再确定第二小元素,最后确定最大元素。他的主要流程如下:
1.数组A = {5,3,6,2,4,7},对他进行排序
2.确定最小的元素放在A[0]位置,我们怎么确定呢,首先默认最小元素为5,他的索引为0,然后用它跟3比较,比他大,则认为最小元素为3,他的索引为1,然后用3跟6比,发现比他小,最小元素还是3,然后跟2比,最小元素变成了2,索引为3,然后跟4比,跟7比。当比较结束之后,最小元素也尘埃落定了。就是2,索引为3,然后我们把他放在A[0]处。为了使A[0]原有数据部丢失,我们使A[0](要放的位置) 与A[3](最小数据的位置)交换。这样就不可以了吗?
3.然后我们在来找第二小元素,放在A[1],第三小元素,放在A[2]。。当寻找完毕,我们排序也就结束了。
4.不过,在找的时候要注意其实位置,不能在找A[2]的时候,还用A[2]的数据跟已经排好的A[0],A[1]比,一定要跟还没有确定位置的元素比。还有一个技巧就是我们不能每次都存元素值和索引,我们只存索引就可以了,通过索引就能找到元素了。呵呵。
5.他和冒泡的相似和区别,冒泡和他最大的区别是他发现比他小就交换,把小的放上面,而选择是选择到最小的在直接放在确定的位置
冒泡排序
标签: 算法outputfunctioninputdate2010
2010-06-08 22:47 246人阅读 评论(0) 收藏 举报
分类:
Algorithms(4)
版权声明:本文为博主原创文章,未经博主允许不得转载。
呵呵,冒泡排序很简单,先练练手,贴上代码
/****************************************************************
Function: SORT_Bubble
Date: 2010-06-07
Author: Robbie
Description: 冒泡算法
Input: INT *piData 待排序的数列
UINT uiNum 数列个数
Output:
Return:
Modify:
*****************************************************************/
VOID SORT_Bubble(IN INT *piData, IN UINT uiNum)
{
INT i, j;
INT iTmp = 0;
BOOL_T bflag = BOOL_FALSE; /* 标志,如果已经排好序, 能快速检测出来 */
for (i = 0; (i < (uiNum - 1)) && (BOOL_FALSE == bflag); i++)
{
bflag = BOOL_TRUE;
for (j = (uiNum -1); j > i; j--)
{
if(piData[j] < piData[j - 1])
{
iTmp = piData[j - 1];
piData[j - 1] = piData[j]; /* 小的数冒泡上升 */
piData[j] = iTmp;
bflag = BOOL_FALSE;
}
}
}
}
这里bflag是一个标记,假设数列已经是排好序的,则能检测出来退出。算法的原理就不说了,呵呵!
算法的性能:
若记录序列的初始状态为"正序",则冒泡排序过程只需进行一趟排序,在排序过程中只需进行n-1次比较,且不移动记录;
反之,若记录序列的初始状态为"逆序",则需进行n(n-1)/2次比较和记录移动。因此冒泡排序总的时间复杂度为O(n*n)。