循环插入排序算法
基本思想是将待排序的序列看作是一个已经排好序的序列,然后依次将每个元素插入到前面的有序序列中的适当位置,直到全部元素都被插入。
#include<stdio.h>
#include<stdlib.h>
#define maxsize 100
typedef struct {
int r[maxsize];
int length;
}SqList;
void sort(SqList & L) {
int k = L.length, i, j, first, final;
int d[k] = { 0 }; // 创建一个临时数组d,用于存储已排序的部分
d[0] = L.r[1]; // 将第一个元素放入d的第一个位置
first = final = 0; // 初始化first和final为0,表示有序部分的起始和结束位置
// 循环遍历剩余的元素
for (i = 2; i <= k; i++) {
// 如果当前元素大于有序序列的最后一个元素
if (L.r[i] > d[final]) {
final = (final + 1) % k; // 更新final位置
d[final] = L.r[i]; // 将当前元素放入final位置
}
// 如果当前元素小于有序序列的第一个元素
else if (L.r[i] < d[first]) {
first = (first - 1 + k) % k; // 更新first位置
d[first] = L.r[i]; // 将当前元素放入first位置
}
// 当前元素位于有序序列中间的情况
else {
j = final; // 从序列的最后开始查找插入位置
while (L.r[i] < d[j]) {
d[(j + 1) % k] = d[j]; // 向右移动元素
j = (j - 1 + k) % k; // 更新j
}
d[(j + 1) % k] = L.r[i]; // 将当前元素插入到找到的位置
final = (final + 1) % k; // 更新final
}
}
// 将临时数组d中的元素复制回原序列L.r
for (i = 1, j = first; i <= k; i++, j = (j + 1) % k) {
L.r[i] = d[j];
}
}
int main() {
SqList L;
int i;
scanf("%d", &L.length);
for (i = 1; i <= L.length; i++) {
scanf("%d", &L.r[i]);
}
sort(L);
for (i = 1; i <= L.length; i++) {
printf("%d ", L.r[i]);
}
return 0;
}
这段代码中,L是一个顺序表(SqList),L.length表示顺序表的长度。算法首先将第一个元素作为已排序序列的起点,并逐步将剩余的元素插入到适当的位置。为了处理序列的循环特性(即避免数组越界),使用了模运算来计算first和final的下一个位置。
循环插入排序算法的时间复杂度为O(n^2),其中n是待排序序列的长度。虽然在平均和最坏情况下的性能都较好,但对于大规模数据并不高效。