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

对已知数组进行直接插入排序,过程如下:

                         a[0]     a[1]     a[2]     a[3]     a[4]

初始序列:                  36       20       18       60   

                                      a[1]>a[2]

a[0]=a[2]          20      36       20        18       60

                          20      20       36        18      60

                                                    a[2]>a[3]

a[0]=a[3]          18       20      36        18       60

                          18      18       20        36      60

                                                             a[3]<a[4]

                                    18       20        36       60



直接插入排序代码实现如下:

#include<stdio.h>
//对已知数组进行直接插入排序
int main(){
	int n,i,*a,j;
	printf("请输入数组元素的个数:\n");
	scanf("%d",&n);	//输入数组元素的个数
	a=(int *)malloc(sizeof(int*)*(n+1));//动态生成数组
	printf("请输入数组元素:\n");
	for(i=1;i<=n;i++){
		scanf("%d",a+i);
	}	
	//在直接插入排序中数组是从下标为1的地方开始存放数值
	for(i=2;i<=n;i++){
		if(a[i]<a[i-1]){
			a[0]=a[i];//如果当前元素比前一个元素值小,就把当前元素赋值给a[0],否则直接扫描下一个元素
			for(j=i-1;j>0;j--){//从当前已经有序的那一部分数组元素的最后一个元素开始依次进行比较,即j指向的是已经有序的那部分元素的最后一个元素
				if(a[j]>a[0]){
					a[j+1]=a[j];//如果比插入的元素大,那么当前比较的元素就后移
				}else{
					break;//因为前面的部分元素已经有序,因此不满足条件,即可跳出当前循环
				}
			}
			a[j+1]=a[0];//将需要插入的数插入到数组中合适的位置
		}
	}
	printf("对数组进行直接插入排序的结果如下:\n");
	for(i=1;i<=n;i++){
		printf("%d\t",a[i]);
	}
	return 0;
}

#include<stdio.h>
//对未知数组进行边输入边排序,数组始终有序
int main(){
	int *a,n,m,temp,k,i;	
	printf("请输入参与排序的数的个数:\n");
	scanf("%d",&n);	//记录一共有多少个数参与排序
	a=(int *)malloc(sizeof(int*)*(n+1));	//动态生成数组,为避免在程序中发生数组越界,生成数组时把长度+1
	printf("请输入第1个需要排序的数:\n");
	scanf("%d",&a[0]);	//第一个数不需要进行比较就可以直接放入排好序的数组中
	printf("对%d进行排序的结果:\n",a[0]);
	printf("%d\n",a[0]);
	n--;	//已经输入一个数,因此需要减1
	m=0;	//m指向排好序的数组中最后一个不为0的元素
	while(n--){
		printf("请输入第%d个需要排序的数:\n",m+2);
		scanf("%d",&temp);	//把需要排序的数赋值给临时变量,而不是直接赋值给排序数组
		k=m;
		while(temp<a[k]&&k>=0){	
			/*
			k指向的是与输入的数进行比较的当前数组元素的下标;
			如果输入的数比数组元素小,那么该数组元素就必须右移
			*/
			a[k+1]=a[k];
			k--;
		}
		a[k+1]=temp;	//将输入的数据写入数组中合适的位置,构成一个有序数组
		m++;	//因为数组增加了一个新的元素,所以m任然指向有序数组的最后一个不为0的元素
		printf("对%d进行排序的结果:\n",temp);
		for(i=0;i<=m;i++){
			printf("%d\t",a[i]);
		}
		printf("\n");
	}
	return 0;
}


	



折半插入排序和直接插入排序很相近,只是在寻找插入的位置时不同。直接插入排序是直接查找,折半插入排序是折半查找,与直接插入排序相比只是减少了比较的次数。直接插入排序和折半插入排序时间复杂度都为O(n^2)。

折半插入排序代码实现如下:

#include<stdio.h>
//对已知数组进行折半插入排序
int main(){
	int n,*a,i,low,high,mid,j;
	printf("请输入排序数组的长度:\n");
	scanf("%d",&n);//n表示数组的长度
	a=(int*)malloc(sizeof(int*)*(n+1));//避免在后面的计算中发生数组越界,初始化的时候数组的长度可稍微增大
	printf("请输入数组的元素:\n");//对数组输入值时从下标为1开始,因为a[0]用来存放每次需要进行排序的那个数
	for(i=1;i<=n;i++){
		scanf("%d",a+i);
	}
	printf("排序前的数组为:");
	for(i=1;i<=n;i++){
		printf("%d\t",a[i]);
	}
	printf("\n");
	for(i=2;i<=n;i++){//插入排序是在前面一部分元素有序时,对另外一个数进行插入并且使之有序。所以i=1的情况只有一个元素不需要考虑
		a[0]=a[i];//将需要进行插入排序元素赋值给a[0]
		//low是第一个有序数的下标
		low=1;//high是最后一个有序数的下标
		high=i-1;
		while(low<=high){//在low和high之间寻找元素a[0]应该插入的位置
			mid=(low+high)/2;
			if(a[0]<a[mid])
				high=mid-1;
			else
				low=mid+1;
		}
		//从最后一个有序数开始一直到元素应该插入的位置的下标,依次后移
		for(j=i-1;j>=high+1;j--){
			a[j+1]=a[j];
		}
		a[high+1]=a[0];//将a[0]赋值给其应该插入的位置
	}
	printf("排序后的数组为:");
	for(i=1;i<=n;i++){
		printf("%d\t",a[i]);
	}
	printf("\n");
	return 0;
}








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值