【苏瞳】C语言+插入排序+希尔排序

目录

插入排序

希尔排序


插入排序

要想理解希尔排序 O(logN * N),首先你必须理解直接插入排序 O(N^2)

直接插入排序思想就是:[0, end] 已经有序,把 end+1 位置的值插入前面,使得 [0,end+1]有序

话不多说上代码,注释详细

#include<stdio.h>
 
//直接插入排序 O(N^2)
//最坏 ?逆序 1+2+3+...+n-1 
//最好 ?顺序 O(N) 
void InsertSort(int *arr,int Size)
{
	for(int i=0; i<Size-1; i++)
	{
		//如果下标[0,end]有序,把 end+1 插入后 [0,end+1] 有序
		//i<Size-1   即end最后一个位置是Size-2 -> 倒数第二个位置,如果到倒数第一个位置,end+1会越界 
		int end=i;
		int temp=arr[end+1];
		while(end >= 0)//最多插入在第一个位置 
		{
			if(arr[end] > temp)//只要插入的值要比前一个小,前一个就往后挪一位
			{
				arr[end+1]=arr[end];
				end--; 
			}
			else
			{
				break;
			}
		}
		//如果 1.break到这里就是找到比temp小的了 2.while循环走完结束到这里end == -1了
		arr[end+1]=temp; 
	} 

}

int main()
{
	int arr[]={5,2,1,4,3};
	InsertSort(arr,5);
	for(int i=0;i<5;i++)
	{
		printf("%d ",arr[i]);
	} 
	return 0;
}


希尔排序

显然直接插入排序的效率不高,优化后 -> 希尔排序

希尔排序就是把相隔gap距离的分成一组,首先进行预排序,使数组几乎接近有序,这样就可以使插入排序效率大大提高,注意是相隔gap,不是每gap个一组

如下图 例如 gap=3

gap=3,预排序完如下图:

显然这时候再进行直接插入排序效率会更高

在实际中gap不能固定为3,所以每次需要使gap变动(这里方法不唯一,可以gap每次除2),使它和数组Size有关,但最后一次gap必须是1,这样才能使他完全有序。

可以与上面的直接插入排序比较 内部循环 ,就是把上面的1改为了gap,代码如下(详细注释):

#include<stdio.h>

//直接插入排序的优化 -> 希尔排序
//1.先进行预排序(分组排,每间隔gap一组),让数组接近有序(这样可以让直接插入排序效率更高) 
//2.直接插入排序 -> O(N) 
//时间复杂度O(log3N * N) 或者 O(logN * N)
void SheelSort(int *arr,int Size)
{
	int gap=Size;
	
	while(gap > 1)
	{
		//gap >1 时都是预排序          ->接近有序 
		//gap==1 时就是直接插入排序    ->完全有序 
		//或者gap=gap/3 + 1; 
		gap=gap/2; //除2可以保证最后一次gap==1 -> 变成完全有序 
		for(int i=0; i<Size-gap; i++)//把间隔为gap的多组数据同时排,最后i == Size-gap-1 
		{
			int end=i;
			int temp=arr[end+gap];
			while(end >= 0)
			{
				if(arr[end] > temp)
				{
					arr[end+gap]=arr[end];
					end=end-gap;
				}
				else
				{
					break;
				}
			}
			arr[end+gap]=temp;
		}
	}
}


int main()
{
	int arr[]={5,2,1,4,3};
	SheelSort(arr,5);
	for(int i=0;i<5;i++)
	{
		printf("%d ",arr[i]);
	} 
	return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值