数据结构:(直接插入排序与希尔排序)

1.直接插入排序

1.排序思路

假设待排序的元素存放在数组 R [ 0.. n − 1 ] R[0..n-1] R[0..n1]中,在排序过程中的某一中间时刻, R R R被划分成为两个子区间 R [ 0.. i − 1 ] R[0..i-1] R[0..i1] R [ i . . n − 1 ] R[i..n-1] R[i..n1],其中前一个子区间是已经排好序的有序区(ordered region),后一个子区间则是当前为排序的部分,不妨设其为无序区(disordered region),初始时i=1,即有序区只有 R [ 0 ] R[0] R[0]一个元素。
直接插入排序(straight insertion sort)的一趟操作是将当前无序区的开头元素 R [ i ] ( 1 ⩽ i ⩽ n − 1 ) R[i](1\leqslant i\leqslant n-1) R[i](1in1)插入到有序区 R [ 0.. i − 1 ] R[0..i-1] R[0..i1]中的适当位置,使 R [ 0.. i ] R[0..i] R[0..i]变为新的有序区。
那么,对于第i趟排序,如何将无序区的第一个元素 R [ i ] R[i] R[i]插入到有序区呢?
其过程是先将 R [ i ] R[i] R[i]的值存储在临时变量 t e m p temp temp中,索引 j j j在有序区从后往前找(初值为 i − 1 i-1 i1),凡是数组元素值大于temp的,均往后移动一个位置。若找到某个 R [ j ] R[j] R[j],其值小于或等于 t e m p temp temp,则将 t e m p temp temp放在它们的后面,即置 R [ j + 1 ] = t e m p R[j+1]=temp R[j+1]=temp;
具体的过程如下述GIF动图所示:
在这里插入图片描述

2.排序算法

void InsertSort(int R[], int n) { //对R[0..n-1]按递增有序进行直接插入排序
	int i, j, int temp;
	for (int i = 1; i < n; i++) {
		if (R[i] < R[i - 1]) {//如果R[i]>=R[i-1] 则保持R[i]的位置不变
			temp = R[i];
			j = i - 1;
			do { //找R[i]的插入位置
				R[j + 1] = R[j];
				j--;
			} while (j >= 0 && R[j] > temp);
			R[j + 1] = temp; //在j+1处插入R[i]
		}
	}
}

3.算法分析

时间复杂度:平均 O ( n 2 ) O(n^2) O(n2),最好 O ( n ) O(n) O(n),最差 O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( 1 ) O(1) O(1)
稳定性:稳定

2.希尔排序

1.排序思路

希尔排序(shell sort)也是一种插入排序方法,实际上是一种分组插入方法。其基本思想是先取一个小于n的整数 d 1 d_{1} d1作为第一个增量,把表的全部元素分成 d 1 d_{1} d1组,将所有距离为 d 1 d_{1} d1的倍数的元素放在同一个组中。在各组内进行直接插入排序;然后第2个增量 d 2 ( < d 1 ) d_{2}(<d_{1}) d2(<d1),重复上述的分组和排序,直到所取的增量 d t = 1 ( d t < d t − 1 ⋯ d 2 < d 1 ) d_{t}=1(d_{t}<d_{t-1}\cdots d_{2}<d_{1}) dt=1(dt<dt1d2<d1),即所有元素放在同一组中进行直接插入排序为止。
具体过程如下GIF动图所示:
在这里插入图片描述

2.排序算法

//希尔排序
void ShellSort(int R[],int n) {
	int i, j, d;
	int temp;
	d = n / 2; //对增量置初值
	while (d > 0) {
		for (int i = d; i < n; i++) { //对所有组采用直接插入排序
			temp = R[i];
			j = i - d;
			while (j >= 0 && temp < R[j]) {
				R[j + d] = R[j];
				j = i - d;
			}
			R[j + d] = temp;
		}
		d = d / 2;//减小增量
	}
}

3.算法分析

时间复杂度: O ( n 1.3 ) O(n^{1.3}) O(n1.3)
空间复杂度: O ( 1 ) O(1) O(1)
稳定性:不稳定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

散一世繁华,颠半世琉璃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值