排序——插入排序 主要包括:《直接插入排序》《希尔排序》

这里我们就实现这俩个,我觉的有点太多了的话,我们也看不进去,我把剩下的,《选择排序》《交换排序》《归并排序》《非比较排序》在另外写几篇博客,我会把下面的链接到时候发在下面,这样就比较好看;

插入排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89345756
选择排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89363420
交换排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89394853
归并排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89449893
非比较排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89449893

排序:所谓的排序,大概的意思就是让无序的数列,变成有序。

一,插入排序

首先,我们要先了解一下,插入排序的思想:就是把待排序按其关键码值插入到有序的排列中,直到所有的排序都排完,完成一个新的序列。

(1)直接插入排序

直接插入的思想就是:《这里主要是我都思想将进行插入一个值的时候, 就把前面插入进去,并且已近排序好了的顺序,在于之前的遍历一遍,找到合适的位置,然后在插入到此排序链中,形成行的排序,重复此过程就完成排序了。

下面我们看一下实现的代码;

#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include<malloc.h>
void Print(int* a, int n)   //实现函数的调用
{
	int i = 0;
	for (i = 0; i <= n - 1; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}
void InsertSort(int* a, int n) //插入排序——直接插入
{
	int i = 0;
	for (i = 0; i < n - 1; i++)
	{
		int end = i;
		int tmp = a[end + 1];
		while (end >= 0)
		{
			if (a[end] > tmp)
			{
				a[end + 1] = a[end];
				--end;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;
	}
}
int main()
{
	int a[] = { 1, 2, 5, 6, 9, 8, 7, 4, 3 };
	InsertSort(a, sizeof(a) / sizeof(int));   
	Print(a, sizeof(a) / sizeof(int));
		return 0;
}

这里就是我们实现的在插入排序中的直接插入排序,很简单,也很好理解,好好看一下代码,不理解的话,可以在下面的评论区群论,哈哈

(2)希尔排序

希尔排序的思想:(这里主要是我的理解)主要就是,我们先选择一个整数,按照一定的间距,然后排序,比如,间隔为2.就是 1,3,5,7,9等等排过去,把第一遍遍历过后,然后在下面的时候第二次便利的时候,我们把组织然后再变一下,比如第二次变成1,2,3,4,5,6这样遍历,我们把选定的值成为 gap,然后让gap变就可以了,重复上面的循环,这样就是实现希尔排序;
下面,我们先看一下,我画的图片,比较容易理解;
在这里插入图片描述
下面我们就是实现希尔排序,看一下实现代码:

void ShellSort(int* a, int n)
{
	int i = 0;
	int gap = n;
	int end = 0;
	int tmp = 0;
	while (gap > 1)
	{
		gap = gap / 3 + 1; //这里为什么是这个,在下面的时候,我会解释;
		for (i = 0; i <= n - gap - 1; i++)
		{
			end = i;
			tmp = a[end + gap];
			while (end >= 0)
			{
				if (a[end] > tmp)
				{
					a[end + gap] = a[end];
					end -= gap;  //间距是gap,每次比较的也是gap
				}
				else
				{
					break;
				}
				a[end + gap] = tmp;
			}
		}
	}
}

我相信,大家在疑惑为什么是:gap = gap / 3 + 1;,那是因为,比如我们是7个数,我们除3,取中间的值那应该是3,但是我们算下来是2,所以要加你,且这次gap的间隔是3,下次我们还要减小,但剩下2,或者3个数的时候,我们除,就是0,或者1,不对,我们要的是 1 或者是 2 ,所以我们要在这里加1;

下面我们再看一下,这两种排序的实现快慢,且在常用的时候使用哪一种方法比较好?
我们看一下下面的一段代码,我们来跑一下:

void TestSortOP()
{
	const int n = 100000;
	int* a1 = (int*)malloc(sizeof(int)*n);
	int* a2 = (int*)malloc(sizeof(int)*n);
	srand(time(0));
	for (int i = 0; i < n; ++i)
	{
		a1[i] = rand();
		a2[i] = a1[1];
}
size_t begin1 = clock();
InsertSort(a1, n);
size_t end1 = clock();

size_t begin2 = clock();
ShellSort(a2, n);
size_t end2 = clock();

printf("%u\n", end1 - begin1);
printf("%u\n", end2 - begin2);

}

我们看一下执行的程序;
在这里插入图片描述
当我们随机给出100000个数据的时候,插入排序用了10s多,儿希尔排序用了不到一秒,相当于0秒一样,通过测试,我们就可以看出,希尔排序的速度是非常块,建议的话,我们如果要使用插入排序的话,那么就是用希尔排序;

下面我们来总结一下直接插入排序和希尔排序;

我们先看一下直接插入排序;

我们通过上面的复习,我们知道:

1. 元素集合越接近有序,直接插入排序算法的时间效率越高
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1),它是一种稳定的排序算法
4. 稳定性:稳定

下面我们再看一下希尔排序:

通过我们上面的学习;

1.希尔排序是对直接排序的优化
2. 时间复杂度:O(N^1.3 ~ N ^2)
3.稳定性:稳定
4. 当gap>1的时候。都是预排序,只有当gap==1的时候,数组就已经接近有序了,这时候就算是完成排序了;

这里我们就实现这俩个,我觉的有点太多了的话,我们也看不进去,我把剩下的,《选择排序》《交换排序》《归并排序》《非比较排序》在另外写几篇博客,我把下面的链接发在下面;

插入排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89345756
选择排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89363420
交换排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89394853
归并排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89449893
非比较排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89449893

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值