直接插入排序和折半插入排序

1.直接插入排序

1.1 插入排序(insertion sort)的基本思想:

        每次将一个待排序的记录,按其关键字大小插入到前面已经排序好的序列中,直到全部记录插入完成为止.

1.2 基本过程

        假设待排序的记录存放在数组R[1..n]中。初始时,R[1]自成1个有序区,无序区为R[2..n].从i = 2起直到i = n 为止,依次将R[i]插入当前的有序区R[1..i - 1]中,生成含n个记录的有序区.

1.3 基本方法

       将待插入记录R[i]的关键字从右向左依次与有序区中记录R[j](j=i - 1, i - 2, ....,1)的关键字比较:

              1.若R[j]的关键字大于R[i]的关键字,则将R[j]后移一个位置

              2.若R[j]的关键字小于或等于R[i]的关键字,则查找过程结束,j + 1即为R[i]

1.4 插入位置

      关键字比R[i]的关键字大的记录均已后移,所以j + 1的位置已经腾空,只要将R[i]直接插入到此位置即可完成一趟直接插入排序

时间复杂度

      当数组和要求排序的顺序相同时,为o(n)

      当数组和要求排序的顺序相反时,为o(n * n)

      平均时间复杂度为o(n * n)

空间复杂度

      O1

稳定排序

完整c代码

//首先实现简单数据结构的直接插入排序—数组
#include<stdio.h>
#include<stdlib.h>
#define SIZE 5

//直接插入排序子函数
void StrInsertionSort(int *iptr,int size)
{
	int i=1;
	int j;
	int temp;//temp为中间变量,用于与前i-1个已排好序的元素比较
	for(i=1;i<size;i++)
	{
		temp=*(iptr+i);//temp为要插入的元素
		for(j=i-1;j>=0;j--)//对前i-1个与temp比较
		{
			if(*(iptr+j)>temp)
			{
				*(iptr+j+1)=*(iptr+j);
				*(iptr+j)=temp;//
			}				
		}
		//*(iptr+j+1)=temp;
	}
}
//主函数
int main()
{
	int arr[SIZE];
	int k;
	printf("依次输入数组各元素\n");
	for(k=0;k<SIZE;k++)
	{
		scanf("%d",arr+k);
	}
	printf("输出没有排序的数组各元素:\n");
	for(k=0;k<SIZE;k++)
	{
		printf("%d  ",*(arr+k));
	}
	//对数组进行直接插入排序
	StrInsertionSort(arr,SIZE);
	printf("\n排序后输出数组各元素:\n");
	for(k=0;k<SIZE;k++)
	{
		printf("%d  ",*(arr+k));
	}
	printf("\n");
}

2. 折半插入排序

2.1折半插入排序的过程:

      在一个有序序列中,插入关键字和折半序列的中间关键字进行比较,若小则在关键字左边,若大则在关键字右边。

说明:

       折半插入排序只是减少了记录进行比较的次数,记录后移量没变。

//折半插入排序子函数
void zhebanInsertionSort(int *iptr,int size)
{
	int i=1;
	int j;
	int low,high,m;
	int temp,mid_temp;
	//temp为中间变量,用于与前i-1个已排好序的元素中间值比较
	//mid_temp为以排好序的序列中间值
	for(i=1;i<size;i++)
	{
		low=0;
		high=i-1;
		temp=*(iptr+i);//temp为要插入的元素
		while(low<=high)//循环找到要移动的位置下限,high+1
		{
			m=(low+high)/2;
			mid_temp=*(iptr+m);
			if(temp>mid_temp)
			{
				low=m+1;
			}
			else high=m-1;
		}
		//移动元素,往后统一挪
		for(j=i-1;j>=high+1;j--)//
		{		
			*(iptr+j+1)=*(iptr+j);
			*(iptr+j)=temp;//
		}
	}
}

时间复杂度

        当数组和要求排序的顺序相同时,为o(n)

        当数组和要求排序的顺序相反时,为o(n * n)

        平均时间复杂度为o(n * n)

空间复杂度

        O1

稳定排序





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值