2-路插入排序是在折半插入排序的基础上再改进之,减少移动记录的次数,但需要n个记录的辅助空间。
#include<iostream>
using namespace std;
//第十章 内部排序
//待排记录数据的数据结构
#define maxsize 20
struct redtype{
int key;
};
struct Sqlist
{
redtype r[maxsize];
int length;
};
int buildsq(Sqlist &sq){
int x;
cin>>x;
sq.length=x+1;
for(int i=1;i<=x;++i)
{int p;
cin>>p;
sq.r[i].key=p;
}
return x;
}
//插入排序
//2-路插入排序
void twoinsertsort(Sqlist &sq, int length){//建立一个数组d,看成一个循环量。并设立first和final两个指针,标识第一个记录和最后一个记录
//在插入过程中不断的的移动指针, 最难的是运用取余 防止溢出
int d[length];
int first,finals;
first=finals=0;//刚开始两指针都指向第一个元素
d[0]=sq.r[1].key;//待排第一个记录赋值给辅助数组d,
for(int i=2;i<=length;++i){ //从第二个记录开始插入排序
if(sq.r[i].key<d[first]){ //小于第一个元素,插入first之前。
first=(first-1+length)%length;//利用取余得到first前一个位置
d[first]=sq.r[i].key;//插入
}
else if(sq.r[i].key>d[finals]){ //大于最后一个元素,插入final后一个位置
++finals;
d[finals]=sq.r[i].key;
}
else {//大于first指向的元素且小于final指向的元素,插入中间,此时会元素移动
int j=++finals;
while(sq.r[i].key<d[(j-1+length)%length]){//从final位置的元素向前比较,得到元素该插入的位置
d[(j+length)%length]=d[(j+length-1)%length];//移动元素
j=(j-1+length)%length;//向前移动一位,继续比较
}
d[(j+length)%length]=sq.r[i].key;//插入
}
}
for(int i=1;i<=length;++i){//把d数组已排序好的元素赋值回去
sq.r[i].key=d[(first+i-1)%length];
}
}
int main(){
Sqlist sq;
int t= buildsq(sq);
twoinsertsort(sq,t);//2-路插入排序
for(int i=1;i<=t;++i){
cout<<sq.r[i].key<<" ";
}
return 0;
}
运行结果: