八大排序--直接插入排序

直接插入排序:一开始将数据分为两部分,初始数据当做无序,每一次从待排序队列中取出一个值,放到我们已经排序好的队列中,然后将其调整有序,然后再从待排序队列中取一个值,直到待排序队列中没有值,再结束。

调整规则:将待插入的值和有序队列中的所有值挨个比较(从右向左),找到一个小于或者等于自己的值,则停下来,插入到当前位置的下一个位置。要么触底要么找到合适的位置

直接插入排序的特点:1.时间复杂度过大O(n^2)合适的使用场景:n比较小的时候

2.数据越有序,则直接插入排序的效率越高 

这幅图对应方法1:其中i代表的是趟数,j代表这一趟开始的时候已排序队列中的最后一个值的下标,从图中可以很容易看出每一次j 都是与 i 相差1的,所以他们的关系式为:j = i -1 ;

 代码实现(方法一):

#include<stdio.h>
#include<stdlib.h>
#include<vld.h>
#include<assert.h>

/*
 稳定性:如果排序之前 3在3'的前面 但是排序后 3跑到了3'的后面 则认为他不稳定
1.直接插入排序:每一次从待排序队列中去一个值放到已排序队列中,然后调整有序,然后再取在排序,直到待排队列没有值
*/

//直接插入排序 时间复杂度O(n^2)  空间复杂度O(1)  稳定性:稳定的
void InsertSort(int* arr, int len)
{
	//assert arr!=NULL;
	for (int i = 1; i < len ;i++) //代表一共跑的趟数
	{
		int j;
		int tmp = arr[i];//带插入的值
		//j指向 这一趟开始的时候的已排序好的队列的最后一个值的下标
		for (j = i - 1; j >= 0;j--)//这里控制待插入的值和已排序队列的挨着比较(从右往左排序)
		{
			if (arr[j] <= tmp) 
			{
				break;//这时应该停下来
			}
			else
			{
				arr[j + 1] = arr[j];
			}
		}
		arr[j + 1] = tmp;
	}
}

void Show(int arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

int main()
{
	int arr[] = { 12,2,39,88,4,6,25,232,62,221 };
	InsertSort(arr, sizeof(arr) / sizeof(arr[0]));
	Show(arr, sizeof(arr) / sizeof(arr[0]));

	return 0;
}

调试结果为:

这幅图对应方法2:因为第一趟排序是可以省略的,而图中,每一次j 都是与 i 指在同一个位置的,所以在这幅图中i与j的关系为:j = i ;

代码实现(方法二):

#include<stdio.h>
#include<stdlib.h>
#include<vld.h>
#include<assert.h>

void InsertSort1(int* arr, int len)
{
	//assert arr!=NULL;
	for (int i = 0; i < len-1; i++) //代表一共跑的趟数
	{
		int j;
		int tmp = arr[i+1];//带插入的值
		//j指向 这一趟开始的时候的已排序好的队列的最后一个值的下标
		for (j = i ; j >= 0; j--)//这里控制待插入的值和已排序队列的挨着比较(从右往左排序)
		{
			if (arr[j] <= tmp)
			{
				break;//这时应该停下来
			}
			else
			{
				arr[j + 1] = arr[j];
			}
		}
		arr[j + 1] = tmp;
	}
}

void Show(int arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

int main()
{
	int arr[] = { 12,2,39,88,4,6,25,232,62,221 };
	InsertSort1(arr, sizeof(arr) / sizeof(arr[0]));
	Show(arr, sizeof(arr) / sizeof(arr[0]));

	return 0;
}

调试结果为:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值