内部排序算法汇总

排序分为内部排序和外部排序两大类:

以下均为内部排序

直接插入排序

说明:

基本思想:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。

例如,已知待排序的一组纪录r[10]是:

10,9,8,7,6,5,4,3,2,1

假设在排序过程中,前3个纪录已按关键码值递增的次序重新排列,构成一个有序序列:

8,9,10

将待排序纪录中的第4个纪录(即7)插入上述有序序列,以得到一个新的含4个纪录的有序序列。首先,应找到7的插入位置,再进行插入。可以将7放入一个临时变量中,这个变量称为监视哨,然后从10起从右到左查找,7小于10,将10右移一个位置,7小于9,又将9右移一个位置,以此类推,直到数组遍历完,此时7是最小的,8,9,10均有后移,因此,将7放到r[0]。假设7大于第一个值r[0]。它的插入位置应该在r[0]和r[1]之间,由于9已经右移了,留出来的位置正好留给7.后面的纪录依照同样的方法逐个插入到该有序序列中。若纪录数是n,则进行n-1趟排序,才能完成。

时间复杂度为O(n^2),是稳定的排序方法。

特点:比较和移动次数多

c实现:

/**
 * 直接插入排序
 */
#define MAXSIZE 10
void directInsertSort(int number[]) {
    int temp;
    for(int i = 1; i < MAXSIZE; i++) {
        temp = number[i];
        int j = i-1;
        for(; j >= 0; j--)
        {
            if(temp < number[j])
                number[j+1] = number[j];
            else
             break;
            
        }
        number[j+1] = temp;
    }
}

希尔排序

说明:

基本思想:先将整个待排记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。

原理:从对直接插入排序的分析得知,其算法时间复杂度为O(n^2),但是,若待排记录序列为“正序”时,其时间复杂度可提高至O(n),由此,若待排记录序列按关键字“基本有序”,直接插入排序的效率就可大大提高,从另一方面来看,由于直接插入排序算法简单,则在n很小时效率也比较高。希尔排序正是从这两点分析出发对直接插入排序进行改进得到的一种插入排序方法。

例如,已知待排序的一组纪录r[10]是:

10,9,8,7,6,5,4,3,2,1

首先将该序列分成5个子序列{r[0],r[5]},{r[1],r[6]},{r[2],r[7]},{r[3],r[8]},{r[4],r[9]},分别对每个子序列进行直接插入排序,排序结果:

5,4,3,2,1,10,9,8,7,6

这称为一趟希尔排序,然后进行第二趟希尔排序,即分别对下列3个子序列{r[0],r[3],r[6],r[9]},{r[1],r[4],r[7]},{r[2],r[5],r[8]}进行直接插入排序,结果如下:

2,1,3,5,4,7,6,8,10,9

最后对整个序列进行一趟直接插入排序。至此,希尔排序结束,整个序列有序。

子序列的构成不是“逐段分割”,而是将相隔某个“增量”的记录组成一个子序列,上面第一趟增量5,第二趟增量3,第三趟增量1.(应使增量序列中的值没有除1以外的公因子,并且最后一个增量值必须等于1


时间复杂度最小为O(n^(3/2)),是稳定的排序方法。

c实现:

/**
 * 希尔排序
 */
#define MAXSIZE 10
void shellInsert(int number[],int dk) {
    
    int temp;
    for(int i = dk; i < MAXSIZE; i++)
    {
        temp = number[i];
        int j = i-dk;
        for (; j >= 0; j = j-dk) {
            
            if(temp < number[j])
                number[j+dk] = number[j];
            else
                break;
            
        }
        
        number[j+dk] = temp;
        
    }
    
}

void shellSort(int number[],int dlta[],int t) {
    for(int i = 0; i < t; i++) {
        shellInsert(number,dlta[i]);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值