直接插入排序


title: 直接插入排序
date: 2020-12-22 16:48:21
tags: 排序算法
categories: 数据结构


直接插入排序,注释中给了比较详细的理解
平均时间复杂度最坏时间复杂度空间复杂度稳定性
O(n^2)O(n^2)O(1)稳定

讲解版

#include <stdio.h>

int main(void)
{
	// 初始化一个数组,0号空间不用,给它赋值成0
	int arr[11] = {0, 0, 8, 5, 1, 2, 9, 4, 3, 7, 6};
	int arrLen = 10;
	// 长度是10, 但是由于0号空间不用,
	// 所以在for循环中,判断条件应该是  < arrLen + 1 或 <= arrLen
	for (int i = 2; i < arrLen + 1; i++) 
	{
		// 比前面已经排好的序列的最后一个小,就插入排序,
		// 如果比前面已经排好的序列的最后一个大,说明这个数直接插最后边就行
		// 所以外层循环直接过就可,不用执行 if 中的语句
		if (arr[i] < arr[i - 1])
		{
			// 进入这个if 就说明要开始插入的流程了

			// 复制哨兵
			arr[0] = arr[i];

			// 给新的数腾地方
			// 因为刚才比较过 arr[i] 和 arr[i - 1]的大小了, 
			// 所以在这里直接腾地方就可
			arr[i] = arr[i - 1];
			// 接着比较前面的,只要比哨兵中的值(哨兵的值即是要插入的新数的值)大
			// 就往后走一个,给新数腾地方
			// 直到遇见一个 >= 要插入的新数的数,
			// 此时循环中断, j 是第一个比新数大的数的下标,
			// 由于j之后的数都挪地方了, 而j比新数大,所以不挪地方
			// 所以将新数放到 j 指向的位置的下一个就行
			int j = i - 2;
			for (j = i - 2; arr[j] > arr[0]; j--)
				arr[j + 1] = arr[j];
			arr[j + 1] = arr[0];
		}
	}
	for (int i = 1; i < arrLen + 1; i++)
		printf("%d\n", arr[i]);
	return 0;
}

封装版

// 数组封装成数据类型
// 排序封装成函数
#include <stdio.h>

#define MAXSIZE 100
typedef struct 
{
	int arr[MAXSIZE + 1];
	// 数组有效长度不包括0号元素
	// 单纯指有效数据的个数
	int length;
}Sql;

void insertSort(Sql *sql)
{
	for (int i = 2; i <= sql->length; i++)
	{
		if (sql->arr[i - 1] > sql->arr[i])
		{
			sql->arr[0] = sql->arr[i];
			sql->arr[i] = sql->arr[i - 1];
			int j;
			for (j = i - 2;sql->arr[j] > sql->arr[0]; j--)
				sql->arr[j + 1] = sql->arr[j];
			sql->arr[j + 1] = sql->arr[0];
		}
	}
}

int main(void)
{
	Sql sql;
	sql.length = 10;
	// 初始化一个倒序数组
	for (int i = 1; i <= sql.length; i++)
		sql.arr[i] = sql.length - i;
	// 打印排序前的数组
	for (int i = 1; i <= sql.length; i++)
		printf("%d ", sql.arr[i]);
	printf("\n");
	// 调用插入排序函数
	insertSort(&sql);
	// 打印排序后的数组
	for (int i = 1; i <= sql.length; i++)
		printf("%d ", sql.arr[i]);
	printf("\n");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值