直接插入排序、希尔排序

本文介绍了两种经典的排序算法——直接插入排序和希尔排序。直接插入排序是一种简单的排序方法,适合小规模或基本有序的数据,时间复杂度为O(n^2)。希尔排序则是对插入排序的优化,通过增量序列逐步减少排序间隔,提高了排序效率。文章详细阐述了这两种排序算法的工作原理,并提供了C语言实现的示例代码。
摘要由CSDN通过智能技术生成

1.直接插入排序

直接插入排序 是一种最简单的排序算法,它的基本操作是将一个记录插入已排好的有序表,从而得到一个新的、记录数增加1的有序表。

例如:设有一个由待排序的一组记录组成的线性表,关键字的初始序列为{48,35,66,91,74,18}。我们可以认为第一个关键字{48}组成的线性表已是有序表;将第二个关键字插入前面的有序表,使之有序,得到序列{35,48};再将第三个关键字插入,使之有序,得到序列{35,48,66};如此重复,直到所有关键字都已插入,完成排序。

直接插入排序思想:

  • (1)假设由前i - 1个记录关键字组成的子序列r[1,…,i-1]已为正序,在子序列中寻找合适位置并插入关键字r[i],使得子序列成为含有i个关键字的正子序列。
  • (2)对有n个记录关键字的序列,重复上述过程至i=n,完成整个序列的直接插入排序。

直接插入排序算法:

typedef struct {
	KeyType r[MAXSIZE + 1];    //0号单元闲置
	int length;    //顺序表长度
}SqList;    //用于排序的顺序表类型

//1.直接插入排序
void Insert(SqList& L, int i) {    //插入第i个记录
	KeyType temp = L.r[i];
	int j;
	for (j = i; j > 1; j--) {
		if (L.r[j] < L.r[j - 1])
			L.r[j] = L.r[j - 1];
		else
			break;
	}
	L.r[j] = temp;
}
void InsertSort(SqList& L) {    //直接插入排序算法
	for (int i = 2; i <= L.length; i++)
		Insert(L, i);
}

2.希尔排序

希尔排序 又称“缩小增量排序”,是一种改进的插入排序,在时间效率上有较大的提高。
通过对直接插入排序的分析可知,其算法时间复杂度为O(n),当待排记录序列有序时,其时间复杂度可以提高至O(n),当待排序列按关键字基本有序时,插入排序的效率可以大幅提高。另一方面,由于直接插入排序法很简单,所以在n值很小时效率也比较高。

希尔排序的基本操作过程是: 先将整个待排记录序列分为若干子序列,分别进行直接插入排序,待整个序列基本有序时,在对全体进行一次直接插入排序。设d为子序列的增量,即在序列中,每间隔d个取一个关键字,组成子序列,。例如进行3趟排序:第一趟,d = 5,分别以1,2,3,4,5记录为起点,每间隔5个记录取一个记录,组成5个记录的子序列然后在原来记录的存储位置上分别对这5个记录子序列进行直接插入排序。第二趟、第三趟分别取d = 3, d = 1。最后一次d = 1,完成整个序列的排序。

希尔排序示例: 以关键字序列{48,35,66,91,74,18,22,48,57,3}为例,d分别取5、3、1。
在这里插入图片描述
希尔排序算法:

//2.希尔排序
void ShellInsert(SqList& L, int d) {    //增量为d的直接插入排序
	//对间隔d的子序列进行直接插入排序
	int i, j;
	KeyType temp;
	for (i = d + 1; i <= L.length; i++) {
		if (L.r[i] < L.r[i - d]) {    //需将L.r[i]插入有序增量子表
			temp = L.r[i];
			for (j = i; j > d; j = j - d) {
				if (temp < L.r[j - d])
					L.r[j] = L.r[j - d];
				else
					break;
			}
			L.r[j] = temp;    //将记录r[i]插入正确位置
		}
	}
}
void ShellSort(SqList& L, int d[], int t) {    //希尔排序
	//按增量序列d[0,...,t - 1],对顺序表L进行希尔排序
	for (int k = 0; k < t; k++)
		ShellInsert(L, d[k]);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值