排序是将一个记录的任意序列,重新排列成一个按关键字有序的序列(按非递减或非递增)。
排序算法按排序过程中依据的不同原则可以大致分为五类:插入排序、交换排序、选择排序、归并排序、基数排序。
下面程序均使无序序列排序成非递减序列。
数据结构使用顺序表,并初始化8个元素 [49,38,65,97,76,13,27,49],
typedef struct Record{
int key; //关键字项
char otherinfo; //其他数据项
};
typedef struct SqList{
Record *r;
int length;
};
main(){
SqList L;
InitList(L);
printf("排序前:");
for(int i = 1;i <= L.length;i ++){
printf("%d ",L.r[i].key);
}
printf("\n直接插入排序后:");
InsertSort(L);
for(int i = 1;i <= L.length;i ++){
printf("%d ",L.r[i].key);
}
printf("\n");
}
main(){
SqList L;
InitList(L);
printf("排序前:");
for(int i = 1;i <= L.length;i ++){
printf("%d ",L.r[i].key);
}
printf("\n直接插入排序后:");
InsertSort(L);
for(int i = 1;i <= L.length;i ++){
printf("%d ",L.r[i].key);
}
printf("\n");
}
一、插入排序
基本操作是将一个记录插入到
已排好序的有序表中,得到一个新的有序表。
1、直接插入排序。最简单的排序方法。
算法思想:从数组第二个元素开始,将前面所有元素视为已排好序的有序表,在其中找到插入位置插入,重复过程直至结束。
void InsertSort(SqList &L){
for(int i = 2;i <= L.length;i ++){
if(L.r[i].key < L.r[i - 1].key){
L.r[0] = L.r[i]; //复制为哨兵 ,大大减少比较次数
L.r[i] = L.r[i - 1];
int j;
for(j = i - 2;L.r[0].key < L.r[j].key;j --){
L.r[j + 1] = L.r[j];
}
L.r[j + 1] = L.r[0];
}
}
}
2、折半插入排序。插入排序的操作可分为“查找”和“插入”,折半插入即使用折半查找来完成查找,能有效减少关键字的比较次数,记录移动次数不变。