数据结构之插入排序

插入排序的一些代码

插入排序有,直接插入排序、折半插入排序、2-路插入排序和表排序。如果了解了这些排序的思路,那么代码也就容易理解了。
  1. 直接插入排序思路是:把第一个当做已排好序的,直接从第二个开始记为当前数据(当前数据需要保存到a[0],把a[0]当做一个哨子)。然后用当前数据跟前面的数据比下去,大于当前数据的数都往后移一位。当找到小于当前数据的数时,把当前数据放进去。如果当前数据就是最大的则不动,直接进入下一次循环。
  2. 折半插入排序跟直接插入排序差不多,只是在找比当前数据小的数的时候用了二分查找法找到属于当前数据的位置,low就是应该插入的位置,但是这只是减少了比较次数,移动次数并没有改变。
  3. 2-路插入排序:用一个循环数组(0-1的时候要再加上数组长度就从0移动到n-1了)第一个放在循环数组的第一个位置(下标为0),first和final都指向第一个,然后从第二个开始。
    如果当前数据大于final,则final++然后把当前数据放在final里面。
    如果当前数据小于first,则(first-1+length)%length然后把当前数据放在first里面.。
    如果当前数据小于final大于first则需要移动当前数据前面所有大于当前数据的数。
  4. 表排序就不写了。
三个插入排序的代码
// An highlighted block
#include<stdio.h>
#include<stdlib.h>
#define LENGTH 8
//直接插入排序
void InsertSort(int a[]){
	printf("直接插入排序\n");
	int i, j;
	for (i = 2; i<9; i++){		
			a[0] = a[i];//保存当前数			
			for (j = i - 1; a[0]<a[j]; --j){//当j遇到a[0]这个哨兵的时候,就停下来了
				a[j + 1] = a[j];
			}
			a[j + 1] = a[0];		
	}
}
//折半插入排序
void InsertSort2(int a[]){
	printf("折半插入排序\n");
	int i,j,m;
	int low,high;
	
	for(i=2;i<9;i++){
		a[0]=a[i];
		low=1;
		high=i-1;
		while(low<=high){
			m=(low+high)/2;
			if(a[0]<a[m])high=m-1;
			else low=m+1;
		}//while
		for(j=i-1;j>=low;--j){
			a[j+1]=a[j];
		}
		a[low]=a[0];//high+1==low;
	}
}

void p2_InsertSort(int a[]){
	printf("2-路插入排序\n");
	int *d=(int *)malloc(sizeof(int)*LENGTH);
	int first,final;
	int i,j;
	first=final=0;
	d[0]=a[1];
	for(i=2;i<=LENGTH;i++){
		if(a[i]<=d[first]){
			first=(first-1+LENGTH)%LENGTH;
			d[first]=a[i];
		}else if(a[i]>=d[final]){
			++final;
			d[final]=a[i];
		}else{
			j=final++;
			while(a[i]<d[j]){
				d[(j+1)%LENGTH]=d[j];
				j=(j-1+LENGTH)%LENGTH;
			}
			d[(j+1)%LENGTH]=a[i];
		}
	}
	for(i=1;i<=LENGTH;i++){
		a[i]=d[(first+i-1)%LENGTH];
	}
	
}

int main()
{
	int i;
	int a[9]={0,38,49,65,97,76,13,27,49};	
//	int a[5]={6,5,4,3,2};
//	p2_InsertSort(a);
//	InsertSort2(a);

	for(i=1;i<9;i++){
		printf("%d\t",a[i]);
	}
	printf("\n");
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值