普通插入排序与改良插入排序(希尔排序)

普通插入排序

手工过程:

例: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);
}

运行结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值