排序

快速排序

 


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现在中枢元素53(5个元素,下标从1开始计)交换就会把元素3的稳定性打乱。(嘿嘿,什么是不稳定排序?非常通俗的讲,在排序前后,相等的两个数的位置顺序不变,这里第5个元素3,原来是是在前面两个3后面,排序后在两个3前面了,因为位置顺序变了,懂了吧,是不是很简单。。。)

 

快速排序的平均时间为knlnnn为待排序个数,k为某个常数,经验证明,在所有同数量级排序方法中,快速排序的常数因子k最小,具体为什么,我也懒得推导了。。。偶也不会。因此,就平均时间而言,快速排序是目前被认为最好的一种内部排序方法。

 

 

 

 

 

插入排序

标签: insertoutputfunctioninputdate2010

2010-06-10 22:54 269人阅读 评论(1) 收藏 举报

 分类:

Algorithms4 

版权声明:本文为博主原创文章,未经博主允许不得转载。

今天复习了一下插入排序,先把代码贴上,后面把原理讲一下

 

 /****************************************************************
    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) 收藏 举报

 分类:

Algorithms4 

版权声明:本文为博主原创文章,未经博主允许不得转载。

呵呵,冒泡排序很简单,先练练手,贴上代码

 

/****************************************************************
    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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值