2-路插入排序

2-路插入排序是在折半插入排序的基础上进行的改进,目的是减少排序过程中记录移动的次数。

算法的思想为:另设一个和原始待排序列L相同的数组D,首先将L[1]复制给D[1],并把D[1]看成是已排好序的序列中处于中间位置的元素,之后将L中的从第二个元素开始依次插入到数组D中,大于D[1]的插入到D[1]之后的序列(此处我称为右半边序列,用的是数组左半部分空间),小于D[1]的插入到D[1]之前的序列(左半边序列,用的是数组右半部分空间)。

2-路插入排序简单的说是以待排序序列中第一个记录为标准将序列分为两部分:小于该记录值的部分和大于该记录值的部分,两个部分都使用折半插入排序来完成排序。

注意:当L[1]中的记录值最小时,2-路插入排序失去它的优越性,等同于折半插入排序

时间复杂度:o(N*N/8)

空间复杂度o(N)

#include<iostream>
#include<vector>
using namespace std;

void BinInsertSort(vector<int> ivec,vector<int> &ivec1){
	int first,final,i,j,low1,high1,mid1,low2,mid2,high2,flag=1;
	first=final=0;  //first记录右半边序列的第一个元素的下标,final记录左半边序列的最后一个元素的下标
	for(i=1;i<ivec.size();i++){
		if(ivec[i]>ivec1[0]){
			low1=0;
			high1=final;
			while(low1<=high1){
				mid1=(low1+high1)/2;
				if(ivec[i]<ivec1[mid1])
					high1=mid1-1;
				else
					low1=mid1+1;
			}
			for(j=final;j>=high1+1;j--)
				ivec1[j+1]=ivec1[j];  //左半边序列右移,腾出待插元素的位置
			ivec1[high1+1]=ivec[i];
			final++;
		}else{
			if(flag==1){
				first=ivec1.size()-1;
				ivec1[first]=ivec[i];
				flag++;
			}else{
				low2=first;
				high2=ivec1.size()-1;
				while(low2<=high2){
					mid2=(low2+high2)/2;
					if(ivec[i]<ivec1[mid2])
						high2=mid2-1;
					else
						low2=mid2+1;
				}
				for(j=first;j<high2+1;j++)
					ivec1[j-1]=ivec1[j];  //右半边序列左移,腾出待插元素的位置
				ivec1[high2]=ivec[i];
				first--;
			}
		}
	}
	cout<<"排序之后的序列为:";
	if(first!=0){  //first为0时表示,待排序序列仅仅进行了左半边的排序,即第一个元素是序列中最小的
		for(i=first;i<=ivec1.size()-1;i++)
			cout<<ivec1[i]<<"  ";
		for(i=0;i<=final;i++)
			cout<<ivec1[i]<<"  ";
		cout<<endl;
	}else{
		for(i=0;i<=final;i++)
			cout<<ivec1[i]<<"  ";
		cout<<endl;
	}
}

void main(){
	vector<int> ivec;
	vector<int>::iterator iter;
	int v;
	cout<<"请输入待排序的序列:";
	while(cin>>v){
		ivec.push_back(v);
	}
	vector<int> ivec1(ivec);
	cout<<"排序之前的序列为:";
	for(iter=ivec1.begin();iter!=ivec1.end();iter++)
		cout<<*iter<<"  ";
	cout<<endl;
	BinInsertSort(ivec,ivec1);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值