排序算法(1)---希尔排序,插入排序,选择法排序

我们所知道的排序算法有多种,根据理解程度以及时间复杂度等不同的要求,选择合适的排序算法。这里对多种排序算法进行说明以及代码实现。

  • 插入排序
  • 希尔排序
  • 选择法排序

在理解希尔排序之前首先对插入排序进行理解,希尔排序是插入排序的特例,跨多步的插入排序,同时希尔排序是不稳定的排序算法。

1.插入排序:从下标为1的元素开始,之后的元素为即将进行插入排序的待排序组,即为A[j],将下标为0的元素作为有序组,即为A[i],其中设j=i-1,每次从待插入组中取出一个元素,与有序组的元素进行比较,若待排元素大于有序元素,则A[j–],一次与有序组元素进行比较,直到找到合适的位置,将该元素插到有序组当中,A[i++]。就这样,每次插入一个元素,有序组增加,待插入组减少。直到待插入组元素个数为0。
其中插入排序不稳定,时间复杂度为O(n),空间复杂度为O(1)。
在这里插入图片描述

2.希尔排序:先取一个小于n的整数a1作为第一个增量,把文件的全部记录分组。所有距离为a1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量a2<a1重复上述的分组和排序,直至所取的增量=1(<…<a2<a1),即所有记录放在同一组中进行直接插入排序为止。实质上是一种分组插入方法。将距离较远的两个数通过在同一个组中进行交换,每个组排序完成后,缩小距离增量,重复步骤,直到增量等于1,排序完成。
同插入排序,希尔排序,时间复杂度 O(n1.3-n1.5),空间复杂度 O(1),不稳定(跳跃式交换数据)

如下图所示,在未采用间隔分组的情况下进行分组排序,即将待排序组进实施成块分组,组内进行排序,效率上十分缓慢,只保证组内有序。
在这里插入图片描述
3.选择法排序:起初数组为无序数组,假设将第一个数字作为最小的数字,从待排序组中找到比当前下标为0的元素最小的元素进行交换,如果没有比当前数组小的则不进行交换,第一个元素为有序组,再从待排序组中找到比第二个元素最小的数字进行交换。每次交换的元素,放到有序组的后面,直到排序完成即可。

在这里插入图片描述

//插入排序

#include<stdio.h>
//大量数据基本有序,采用插入类操作
void InsertSort(int *arr,int len)//直接插入排序:O(n^2),O(1),稳定
{
	int tmp;
	int i;
	int j;
	for(i=1;i<len;i++)//1,2,3,4,5,有序,时间复杂度O(n)
	{
		tmp=arr[i];
		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("%3d",arr[i]);
	}
	printf("\n");
}

int main()
{
	int arr[]={9.0,1,3,6,2,7,8,10,13,12,11,14,16,15};
	int len=sizeof(arr)/sizeof(arr[0]);
	
	InsertSort(arr,len);
	
	Show(arr,len);

	return 0;
}
//希尔排序
#include<stdio.h>

void Shell(int *arr,int len,int gap)
{
	int tmp;
	int i;
	int j;
	for(i=gap;i<len;i++)
	{
		tmp=arr[i];
		for(j=i-gap;j>=0;j-=gap)
		{
			if(arr[j]<=tmp)
			{
				break;
			}
			else
			{
				arr[j+gap]=arr[j];
			}
		}
		arr[j+gap]=tmp;
	}
	
}

void ShellSort(int *arr,int len)
{
	int d[]={5,3,1};
	for(int i=0;i<sizeof(d)/sizeof(d[0]);i++)
	{
		Shell(arr,len,d[i]);
	}
}

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

int main()
{
	int arr[]={20,33,21,54,17,16,30,18,19,22,7,10,46,12,15};
	
	ShellSort(arr,sizeof(arr)/sizeof(arr[0]));
	
	Show(arr,sizeof(arr)/sizeof(arr[0]));

	return 0;
}
#include<stdio.h>

/*
选择法排序:
每次跟待排序序列的后面的元素里面找到比当前数字最小的数字进行交换
复杂度:O(n^2)  O(1)
算法的稳定性:不稳定,跳跃式的交换
*/
void SeleteSort(int *arr,int n)
{
	int tmp=0;
	int minindex=0;
	for(int i=0;i<n;i++)
	{
		minindex=i;
		for(int j=i+1;j<n;j++)
		{
			if(arr[j]<arr[minindex])
			{
				tmp=arr[j];
				arr[j]=arr[minindex];
				arr[minindex]=tmp;
			}
		}
	}
}

void Show(int *arr,int n)
{
	 int m=0;
	 for(;m<n;m++)
	 {
		 printf("% d",arr[m]);
	 }
}
int main()
{
	int arr[]={12,21,3,1,5,2,8,9,5,7};
	int len=sizeof(arr)/sizeof(arr[0]);
	
	SeleteSort(arr,len);
	Show(arr,len);

	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值