0基础入门数据结构与算法之-十大排序算法第二篇(C语言版)

一.上期回顾

1.判断条件改掉,即if(arr[j]<arr[j+1]

2.删除赋值语句arr[0]=arr[low];

二.插入排序

本期的插入排序包括直接插入排序折半插入排序希尔排序三种排序方法,下面,我会依次展开描述。

2.1直接插入排序

原理:对已排好的序列,往其中插入新元素的过程,直接插入排序适用于接近有序(顺序有序时间复杂度最小,逆序有序时间复杂度最大)的序列,这个原理类似我们打牌的抓牌环节,我们手上的牌已排好的前提下抓取一张牌放入合适位置,对于一个数组,我们找到合适的插入位置后,将待插入位置元素及其之后的元素后移,为插入元素腾出空间即可完成排序。案例:定义一个整形数组arr[]={5,9,2,3,1,4,7,6,8},对其进行升序排序。

#include <stdio.h>
//直接插入排序 
void Insertion_sort(int arr[],int length)
{
	//升序 
	int i,j;
	for(j=1;j<length;j++)//j是待插入元素下标 
    {
    	i=j-1;
    	int key=arr[j];
    	while(i>=0&&arr[i]>key)
    	{
    	arr[i+1]=arr[i];
    	i=i-1;
        }
        arr[i+1]=key;//插入元素 
	}
	//验证 
	for(int i=0;i<length;i++)
	printf("%d ",arr[i]);
	printf("\n");
}
int main()
{
int arr[]={5,9,2,3,1,4,7,6,8};
Insertion_sort(arr,sizeof(arr)/sizeof(int));	
return 0;
}

2.2折半插入排序

折半插入排序是相对直接插入排序,明显的优势就是能快速找到插入位置,故时间复杂度相对直接插入排序较高,由于依旧是在有序序列找位置插入元素,所以利用折半方法可以找到插入位置,然后进行元素后移,插入待插元素即可完成排序。

#include <stdio.h>
//折半插入排序 
void half_insertion_sort(int arr[],int length)
{
	//升序 
    for(int i=1;i<length;i++)//依次插入元素 
    {
    int low=1,high=i-1;
    arr[0]=arr[i];//待插元素存于哨兵位置 
    while(low<=high)
    {
    	int mid=(low+high)/2;
    	if(arr[i]<arr[mid])
    	high=mid-1;
    	else
    	low=mid+1;
	}
	//通过分析(你可以手动计算)插入的位置一定是high+1 
	//我们只需将high+1至i-1的元素后移即可
	for(int j=i-1;j>=high+1;j--)
	arr[j+1]=arr[j];
	//插入元素
	arr[high+1]=arr[0];
	}
	//验证 
	for(int i=1;i<length;i++)
	printf("%d ",arr[i]);
	printf("\n");
}
int main()
{
int arr[]={0,5,9,2,3,1,4,7,6,8};
half_insertion_sort(arr,sizeof(arr)/sizeof(int));	
return 0;
}

2.3希尔排序

希尔排序就是通过不断把数据放到不同的区间,来逐步逼近有序的过程,通过间隔序列数组(所有元素满足互质,元素按下表递减,最后一个元素必须是1),通过序列数组长度次的直接插入排序实现整体数组排序。

#include <stdio.h>
//dk为待排序元素的间隔 
void shell_Insert(int array[],int dk,int length)
{
	int i=0,j=0;
	//升序 
	for(i=1+dk;i<length;i++)
	{
		if(array[i]<array[i-dk])
		{
			array[0]=array[i];//哨兵位置存放待插入元素
			for(j=i-dk;j>0&&array[j]>array[0];j-=dk)//j>0防止访问越界 
			array[j+dk]=array[j];
			array[j+dk]=array[0];//插入元素 
		}
	}
}
//希尔排序 
void shell_sort(int array[],int delta[],int t,int length)//参数依次是要排序的数组 间隔序列 以及排序趟数 
{
	for(int k=1;k<=t;k++)
	{
		shell_Insert(array,delta[k],length);
	}
	//验证
	for(int i=1;i<length;i++)
	printf("%d ",array[i]);
	printf("\n"); 
}
int main()
{
int arr[]={5,9,2,3,1,4,7,6,8};
int delta[]={5,3,1};
shell_sort(arr,delta,sizeof(delta)/sizeof(int),sizeof(arr)/sizeof(int)); 
return 0;
}

三.结语

3.1本期疑问

1.如何实现不带哨兵的折半插入排序?

2,分析三种算法的优劣?

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值