直接插入排序算法 ------- C语言

直接插入排序:

 

直接插入排序与我们生活中打扑克牌非常相似

你现在有三张手牌:1,4,6,7,当我们再次抽到 3 这张牌时,往往会习惯性的将他插入到 1 和 4 之间。

这个过程就是一次直接插入排序。 

1.直接插入排序的原理  

已知一段有序的序列,将序列以外的数据插入有序序列中,使得其变成一个新的有序序列

 排序过程

已知序列 { 0,4,5,8,9,3,6,2 }

先从第一个数入手,后一个数与之比较
若后一个数小于前一个数,则交换。
以此类推

序列 { 0 }  4                 4 > 0   不插入
序列 { 0,4 }  5               5 > 4 > 0   不插入
序列 { 0,4,5 }  8             8 > 5 > 4 > 0   不插入
序列 { 0,4,5,8 }  9           9 > 8 > 5 > 4 > 0   不插入
序列 { 0,4,5,8,9 }  3         9 > 8 > 5 > 4 > 3 > 0   插入于0后
序列 { 0,3,4,5,8,9 }  6       9 > 8 > 6 > 5 > 4 > 3 > 0   插入于5后
序列 { 0,3,4,5,6,8,9 }  2     9 > 8 > 6 > 5 > 4 > 3 > 2 > 0   插入于0后

图解 

直接插入排序算法 ------- C语言_第1张图片

  

2.代码实现 

#include

void ArrPrint(const int* a, int n)
{
	int i = 0;
	for (i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
}

void InsertSort(int* a, int n)
{
	int i = 0;
	for (i = 0; i < n - 1; i++)     //for循环遍历数组元素
	{
		int end = i;     //用临时变量end来决定每一步排序开始的位置
		int tmp = a[end + 1];     //用临时变量tmp来存放end的下一个元素的值
		while (end >= 0)     //若end小于0则end已超出数组范围,需跳出while循环
		{
			if (tmp < a[end])     //如果tmp的值小于end,则end向后移动一位 (将 < 改为 > 可变为降序)
			{                                                                          
				a[end + 1] = a[end];
				end--;     //end往前移,使得前一个元素标记为新的end
			}
			else     //若tmp的值大于end,则跳出while循环
			{
				break;
			}
		}
		a[end + 1] = tmp;     //将tmp插入到end的后一位
	}
}

int main()
{
	int arr[] = { 0,4,5,8,9,3,6,2 };  //测试用例
	InsertSort(arr, sizeof(arr) / sizeof(arr[0]));
	ArrPrint(arr, sizeof(arr) / sizeof(arr[0]));
	return 0;
}

代码注意事项 

1. i 的限制

 i 的取值会之间影响到 end ,end 的取值会影响到 tmp,所以若 i 的取值不加以限制,很可能会导致数组的越界访问。

直接插入排序算法 ------- C语言_第2张图片

2.将 tmp 插入放在 while 循环外的妙处 

---  当 tmp 的值小于他前面所有的元素的值时,经过 while 循环后,end = -1,跳出 while 循环执行a[end+1] = tmp; 语句,恰好将 tmp 置于数组首元素位置,即a[0] = tmp

---  当 tmp 的值大于 a[end] 的值时 while 循环内部会执行 else 语句的内容,即 break,跳出 while 循环执行a[end+1] = tmp; 语句,此时也满足排序的目的将 tmp 插入 a[end] 后

3.时间复杂度分析 

当最好情况,也就是排序表本身就是有序的,则只需要进行 n-1 次比较,由于每次都是 arr[i]  >  arr[i+1],没移动记录,时间复杂度为 O(n)。


最坏的情况下,是排序表逆序,需要比较  (n+2)(n-1) / 2 次,移动 (n+4)(n-1) / 2 次。如果排序记录是随机的,根据概率相同的原则,平均比较和移动的次数约为 n^2 / 4 次。
因此,直接插入排序算法时间复杂度为 O(n^2) 

你可能感兴趣的:(算法,c语言,数据结构,排序算法)