编程珠矶学习笔记(11)--插入法排序O(n^2)

18 篇文章 0 订阅

个人原创,转载请注明出处,谢谢!

一、目

input: n个元素的数组;

output: n个元素的有序数组

constrain:使用插入排序法,使数组有序,左小右大

二、算法原理

就像排队,假设个子高的站在右侧,那么如果发现比自己左侧的人个子低,则和他换一下即可,换以后如果发现还比左侧的低,那么继续换,直到比左侧的高为止。比如有下面的4个数字(理解为身高也可):

 

3   1    4   2   5

 

从左向右开始排序,大数在右侧,小数在左侧:

 

1次排序:选3,发现它左侧没有任何数,所以结果为:

3   1    4   2   5

2次排序:选1,比较发现它比左侧的3小,需要交换,所以结果为:

1   3    4   2   5

3次排序:选4,比较发现它比左侧的都大,不用交换,所以结果为:

1   3    4   2   5

 

4次排序:选2,比较发现它比左侧的43都小,需要连续交换,结果为:

1   2    3   4   5

 

5次排序:选5,比较后发现它比左侧的都大,所以不需要交换,结果为:

1   2    3   4   5

排序结束。

三、代码

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

 

/* Data and supporting functions */

#define MAXN 10000000

 

typedef int DType;

 

DType realx[MAXN];

int *x = realx;       /* allow x to shift for heaps */

int n;

 

void swap(int i, int j)

{    

DType t = x[i];

       x[i] = x[j];

       x[j] = t;

}

 

int randint(int l, int u)

{    

return l + (RAND_MAX*rand() + rand()) % (u-l+1);

}

 

/* Simplest insertion sort */

void insert_sort()

{    

int i, j;

       for (i = 1; i < n; i++)

              for (j = i; j > 0 && x[j-1] > x[j]; j--)

                     swap(j-1, j);

}

 

/* Timing */

void timedriver()

{    

int i, mod, start, clicks;

       while (scanf("%d %d", &n, &mod) != EOF) {

              if (mod <= 0)

                     mod = 10*n;

              for (i = 0; i < n; i++)

                     x[i] = randint(0, mod-1);

              k = n/2;

              start = clock();

              isort1(); 

              clicks = clock() - start;

             

              printf("%d/t%d/t%d/t%g/n", n, mod, clicks,

                     1e9*clicks/((float) CLOCKS_PER_SEC*n));

       }

}

 

int main()

{    

timedriver();

       return 0;

}

四、代码注解

 

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

 

/* Data and supporting functions */

#define MAXN 10000000

typedef int DType;

 

DType x[MAXN];

int *x = realx;

int n;

 

/*交换x[i]x[j]的值*/

void swap(int i, int j)

{    

DType t = x[i];

       x[i] = x[j];

       x[j] = t;

}

 

int randint(int l, int u)

{    

return l + (RAND_MAX*rand() + rand()) % (u-l+1);

}

 

/*简单插入法排序 */

void insert_sort()

{    

int i, j;

/*从左向右遍历*/

       for (i = 1; i < n; i++) {

              /*

*对于从0,1,2,3, , i的子数组,从右向左进行比较,

*如果x[i-1] > x[i],则交换它们俩,让小的总在左侧,

              *就像排队,假设个子高的站在右侧,那么如果发现自己

*比自己左侧的人个子低,则和他换一下即可,换以后如

*果发现还比左侧的低,那么继续换,直到比左侧的高为止。

*注意其中的一个结束条件:x[j-1] > x[j]即你(i)比左侧的(i-1)

*低就交换

*/

              for (j = i; j > 0 && x[j-1] > x[j]; j--) {

                     swap(j-1, j);

}

}

}

 

/* 时间驱动函数,用于测试该算法性能*/

void timedriver()

{    

int i, mod, start, clicks;

 

       while (scanf("%d %d", &n, &mod) != EOF) {

              if (mod <= 0) {

                     mod = 10*n;

              }

              /*初始化数组*/

              for (i = 0; i < n; i++) {

                     x[i] = randint(0, mod-1);

}

           start = clock();

           insert_sort ();

           clicks = clock() - start;

             

           printf("%d/t%d/t%d/t%g/n", n, mod, clicks,

                     1e9*clicks/((float) CLOCKS_PER_SEC*n));

       }

}

 

int main()

{    

timedriver();

      return 0;

}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值