待排序的记录序列的3中存储方式
- 顺序表
- 静态链表,对指针(存储的数组下标)进行排序
- 另设一个指示各个记录数据的地址位置的地址向量,对存储对地址进行排序
存储结构
typedef struct{
Keytype key;
InfoType info;
}RedType;
typedef struct{
RedType r[MAXSIXE+1];
int length;
}SqList;
插入排序
- 将一个记录插入到已排好序的有序表中,从而得到一个新的、记录数增 1 的有序表。
- 通过从后向前扫描数组,寻找到(安排列降序还是顺序)插入位置,同时进行元素后移。
- SqList的本质还是为数组,所以在元素插入位置,要将之前的元素进行后移。
void insertSort(SqList &L){
int i=0,j=0;
for(int i=2;i<L.length;i++){
if(L.r[i].key<L.r[i-1].key){
L.r[0] = L.r[i];
/**因为刚才比较到有序列表的最后一个元素位置为SQList的i-1位置,所以从此开始进行后移
*这个比直接写L.r[i] = L.r[i-1]; for(j=i-2;...)......多进行了一次比较
**/
for(j = i-1;L.r[0].key<L.r[j].key;j--){
L.r[j+1] = L.r[j];
}
L.r[j+1] = L.r[0];
}
}
}
折半插入排序
- 在插入排序的基础上,改变比较的方式,使用二分查找法找到插入位置,再把所有大于(小于)关键字的记录后移,并插入到关键位置。
希尔排序(缩小增量排序)
- 算法思想:先将整个待排序的记录序列分割成若干个子序列并分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。
- 子序列的构成不是简单的“逐段分割”,而是将相隔某个“增量”的记录组成一个子序列。
- 逐次缩小增量,如5,3,1
![这里写图片描述](https://img-blog.csdn.net/20171116131241616?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2FueWFucnV4dWU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
void shellInsert(SqList &L,int increment){
int i=0,j=0;
/**
*把每一个子序列视作一个 待直接插入排序的序列
**/
for(i=increment+1;i<L.length;i++){
if(L.r[i].key<L.r[i-increment].key){
L.r[0] = L.r[i];
L.r[i] = L.r[i-increment];
for(j = i-increment;L.r[0].key<L.r[j].key;j-=increment){
L.r[j+increment] = L.r[j];
}
L.r[j+increment] = L.r[0];
}
}
}
void shellSort(SqList &L,int dlta[]){
/**dlta[]中存储增量,如5,3,1,要按降序排列,不然会变成直接插入排序
*(且数组最后一个元素一定为 1,最后进行一次直接插入排序)**/
for(int k=0;k<dlta.length;++k){
shellInsert(L,dlta[k]);
}
}