插入排序(insertion sort)

这篇博客详细介绍了插入排序算法,适用于向量和列表等序列结构。它通过不断将无序元素插入到已排序的前缀中,逐步扩大有序部分。讨论了链表和数组两种情况的插入排序,并提供了C语言的泛型实现。
摘要由CSDN通过智能技术生成

插入排序(insertion sort)

插入排序算法适用于包括向量与列表在内的任何序列结构

​ 插入排序的算法可以简要描述为:始终将序列划分为两个部分: 有序的前缀,无序的后缀;通过迭代,反复的将后缀中的元素移动到前缀中。由此可以看出插入排序算法的不变性:

在任何时刻,相对于当前节点e = S[r], 前缀S[0,r]总是业已有序

​ 算法开始时前缀为空,不变性自然满足。接下来,借助有序序列的查找算法,可在该前缀中定位到不大于e的最大元素。 于是只是需要将e从无序后缀中取出,并紧邻查找返回的位置之后插入,可以使有序前缀的范围扩大至S[0,r]。如此,该前缀范围可不断拓展。当其最终覆盖整个序列时,亦整体有序。

1. 链表的插入排序:

链表的插入删除操作仅需要O(1)时间,但在前缀中搜索插入位置要花费O(n)时间。

/* 列表的选择排序 */
void insertsort(listnode* phead)
{
   
	listnode* curr = phead->next;
	listnode* p = NULL;
	while (curr != NULL) //遍历整个列表
	{
   
		p = curr->next; // 插入操作后列表的结构可能发生改变,要记录后缀开始的位置
		insert(phead, curr); // 节点curr插入到前缀中
		curr = p; // 更新curr至后缀开始的位置
	}
}
/* 节点的插入操作 */
void insert(listnode* phead, listnode* target)
{
   
	listnode* curr = phead->next;
	listnode* prev = phead;
	listnode* p = NULL;
	while (curr != target) // 遍历前缀,寻找插入位置 (prev与curr之间)
	{
   
		if (curr->value > target->value)
			break;
		prev = curr;
		curr = curr->next;
	}
	if (curr == target) // 若不需要交换位置
	{
   
		return; // 直接返回
	}
	p = curr; // 从curr的位置开始
	while (p->next != target) // 找到前缀的末尾节点
	{
   
		p = p->next;
	}
	prev->next = target; // 完成 prev 与 target 的连接
	p->next = target->next; // 前缀的末尾节点指向后缀的开始节点
	target->next = curr; // 完成 target 与 curr 的连接 
}
2. 数组的插入排序(int)
void insertsort(int arr[], int n)
{
   
	int insert = 0; 
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值