文字描述

  在折半插入排序的基础上进行改进, 另设一个和待排序序列L相同的数组D, 首先将L[1]赋值给D[0], 数组D中数据是已经排好序的, first指向最小值下标,final指向最大值下标。初始时,first和final值都为0。之后将L的第二个元素开始依次和D[0]比较,大于D[0]的插入到D[0]之后的序列,小于D[0]的插入到D[0]之前的序列;这里可以将数组D想象成一个循环的圆。

示意图

算法分析

  时间复杂度为n*n, 辅助空间为n,是稳定的排序方法。

  二路插入排序和折半插入排序比,只是可以大概率的减少移动的次数,但不能绝对避免,当待排序序列中的第一个数据就是最小值或者最大值时,2-路插入排序将完全失去它的优越性。

代码实现

 #include <stdio.h>
#include <stdlib.h> #define EQ(a, b) ((a) == (b)) //数a和数b相等则为True,否则为False
#define LT(a, b) ((a) < (b)) //数a小于数b则为True
#define LQ(a, b) ((a) <= (b)) //数a小于或等于数b则为True #define MAXSIZE 20 //待排序数的最多个数
typedef int KeyType; //定义待排序数据的关键字类型为int
typedef int InfoType; //定义待排序数据的其他信息类型为int
typedef struct{
KeyType key; //关键字
InfoType otherinfo; //其他数据项
}RedType; //记录类型 typedef struct{
RedType r[MAXSIZE+]; //r[0]闲置或用作哨兵单元
int length; //顺序表长度
}SqList; //顺序表类型 /*
* 顺序打印序列表L中的关键字
*/
void PrintList(SqList L){
int i = ;
printf("len:%d; data:", L.length);
for(i=; i<=L.length; i++){
printf("%d ", L.r[i].key);
}
printf("\n");
return ;
} #define DEBUG /*
* 2-路插入排序算法的实现
*
* @param
* SqList *L : 待排序的顺序表
*/
void TwoInsertSort(SqList *L)
{
//数组D是和L中关键字列表长度相同的辅助数组
RedType D[MAXSIZE] = {};
//将L中第一个数据存入D[0]
D[] = L->r[]; int i = , j = , n = L->length;
//first表示D中最小值下标,final表示D中最大值下标
int first = , final = ;
int k = ;
#ifdef DEBUG
for(j=; j<n; j++){
printf("%d ", D[j].key);
}
printf("\nthe %d lap:fist=%d, final=%d\n\n", i, first, final);
#endif for(i=; i<=L->length; i++){
if(LT(L->r[i].key, D[first].key)){
// 待插入元素比最小的元素小
first = (first-+n)%n;
D[first] = L->r[i];
}else if(LT(D[].key, L->r[i].key)){
// 待插入元素比最大的元素大
final = (final+)%n;
D[final] = L->r[i];
}else{
// 待插入元素处在最小元素和最大元素中间
// 采用直接插入排序的方法,插入到数组D中合适的位置
k = (final+)%n;
while(LT(L->r[i].key, D[(k-+n)%n].key)){
D[(k+n)%n] = D[(k-+n)%n];
k = (k-+n)%n;
}
D[(k+n)%n] = L->r[i];
final = (final+)%n;
}
#ifdef DEBUG
for(j=; j<n; j++){
printf("%d ", D[j].key);
}
printf("\nthe %d lap:fist=%d, final=%d\n\n", i, first, final);
#endif
}
//将排序记录复制到原来的顺序表里
for(j=; j<n; j++){
L->r[+j] = D[first];
first = (first+)%n;
}
} int main(int argc, char *argv[])
{
if(argc < ){
return -;
}
SqList L;
int i = ;
for(i=; i<argc; i++){
if(i>MAXSIZE)
break;
L.r[i].key = atoi(argv[i]);
}
L.length = (i-); TwoInsertSort(&L);
PrintList(L);
return ;
}

2-路插入排序

运行

[jennifer@localhost Data.Structure]$ ./a.out 12 5 7 4 5 3 45 76
12 0 0 0 0 0 0 0 
the 0 lap:fist=0, final=0

12 0 0 0 0 0 0 5 
the 2 lap:fist=7, final=0

7 12 0 0 0 0 0 5 
the 3 lap:fist=7, final=1

7 12 0 0 0 0 4 5 
the 4 lap:fist=6, final=1

5 7 12 0 0 0 4 5 
the 5 lap:fist=6, final=2

5 7 12 0 0 3 4 5 
the 6 lap:fist=5, final=2

5 7 12 45 0 3 4 5 
the 7 lap:fist=5, final=3

5 7 12 45 76 3 4 5 
the 8 lap:fist=5, final=4

len:8; data:3 4 5 5 7 12 45 76 
[jennifer@localhost Data.Structure]$

最新文章

  1. “(null)” is of a model that is not supported by this version of Xcode. Please use a different device.
  2. September 24th 2016 Week 39th Saturday
  3. Jmeter外部函数引用
  4. [Solution] 简单数字识别之Tesseract
  5. 流媒体学习三-------SIP消息结构详解
  6. 爬虫再探实战(三)———爬取动态加载页面——selenium
  7. 【转载】openldap 备份与导入 及相关问题--扩展
  8. fatal error LNK1168: cannot open Debug/opreat.exe for writing
  9. Android图片与旋转
  10. ARMv8 Linux内核异常处理过程分析
  11. [原创].NET 分布式架构开发实战之一 故事起源
  12. CSS 中的内联元素、块级元素、display的各个属性的特点
  13. jq实现数字增加或者减少的动画
  14. 实战经验丨PHP反序列化漏洞总结
  15. Android OpenGL ES 开发(四): OpenGL ES 绘制形状
  16. SQL Server 锁实验(INSERT加锁探究)
  17. openstack服务启动之nova-compute
  18. IC卡冷复位时序
  19. 描述linux下文件删除的原理
  20. IFE2017笔记

热门文章

  1. TCP中的KeepAlive与HTTP中的Keep-Alive
  2. mysql 核心知识要点
  3. 小技巧 - CSS中:hover调试
  4. const读书笔记
  5. 安卓程序代写 网上程序代写[原]Android应用的自动更新模块
  6. [sso]搭建CAS单点服务器
  7. Gson - 学习
  8. easyradius通讯接口 V4全新升级,显示同步失败原因,方便用户寻找故障
  9. make INSTALL_MOD_PATH=path_dir modules_install
  10. 设计模式-行为型模式,python访问者模式