普通插入排序
手工过程:
例:10 8 6 9 7 6 5 9 2 1
(10) 8 6 9 7 6 5 9 2 1 括号中为已经排好序的数值
(8 10)6 9 7 6 5 9 2 1
(6 8 10)9 7 6 5 9 2 1
(6 8 9 10)7 6 5 9 2 1
(6 7 8 9 10)6 5 9 2 1
(6 6 7 8 9 10)5 9 2 1
(5 6 6 7 8 9 10)9 2 1
(5 6 6 7 8 9 9 10)2 1
(2 5 6 6 7 8 9 9 10)1
(1 2 5 6 6 7 8 9 9 10)排序完成
void directInsertSort(int* arr, int count) {
int i;//待排数据下标
int j;//从0开始,遍历已排数据下标
int tmp;//用作交换数据的临时变量
for(i = 1; i < count; i++) {
for(j = 0; j < i && arr[i] >= arr[j]; j++){
;
}//经过此循环,j停留的位置所在的数据大于当前待排数据,或j=i;
tmp = arr[i];
for(; j < i; i--) {
arr[i] = arr[i - 1];
}
arr[j] = tmp;
}
}
实例验证:
void show(int* arr, int count) {
int i;
for(i = 0; i < count; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
void main() {
int arr[10] = {10, 8, 6, 9, 7, 6, 5, 9, 2, 1,};
printf("排序前:");
show(arr, 10);
directInsertSort(arr, 10);
printf("排序后:");
show(arr, 10);
}
运行结果
插入排序改良版——希尔排序
手工过程
例:
3 9 8 6 4 7 2 5 4 6 8 4 5 4 9 8 2 4 4 7 共20个数据
第一轮:以 20/2 为步长,将下标为:
0 与0+20/2看为一组,进行直接插入排序;
1与1+20/2看为一组,进行直接插入排序;
2与2+20/2看为一组,进行直接插入排序;
…
9与9+20/2看为一组,进行直接插入排序;
第二轮:以 20/2/2 = 5 为步长,将下标为:
0 、5、10、15看为一组,进行直接插入排序;
1、6、11、16看为一组,进行直接插入排序;
2、7、12、17看为一组,进行直接插入排序;
…
4、9、14、19看为一组,进行直接插入排序;
…
最后,以1为步长,进行直接插入排序。
//指定起始下标、步长,进行插入排序
void insertSort(int *arr, int count, int startIndex, int step) {
int i;
int j;
int tmp;
for(i = startIndex + step; i < count; i += step) {
for(j = startIndex; j < i && arr[i] >= arr[j]; j += step) {
}
tmp = arr[i];
for(; i > j; i -= step) {
arr[i] = arr[i - step];
}
arr[j] = tmp;
}
}
void ShellSort(int *arr, int count) {
int step = count;
int start;
for(step >>= 1; step > 0; step >>= 1) {
for(start = 0; start < step; start++) {
insertSort(arr, count, start, step);
}
}
}
实例验证:
void main() {
int arr[10] = {10, 5, 6, 5, 7, 6, 5, 9, 2, 1,};
printf("排序前:");
show(arr, 10);
ShellSort(arr, 10);
printf("排序后:");
show(arr, 10);
}
运行结果