插入排序--直接,折半,希尔排序

直接插入排序

  • 基本思想: 利用顺序查找,在a[1…i-1]有的序列中查找a[i]的插入位置。

  • 算法思想:
    1>在顺序表中查找a[i]的位置k;
    2>将a[k+1…i]的元素往后移一个位置;
    3>将a[i]放在a[k]的位置上;

  • 优化: 可以在比较的同时进行移动,然后直接放到最终的位置。

  • 算法分析: 是一种稳定的排序方法,时间复杂度为o(n2),空间复杂度为O(1)。

#include<iostream>
using namespace std;
void Sort_insert(int a[],int length);//直接插入排序 
void output(int a[],int length);//输出
int main(){
	int a[6]={-1,3,4,5,2,1};
	Sort_insert(a,5); 
	output(a,5);
}
void Sort_insert(int a[],int length){
	for(int i=2;i<=length;i++){
		if(a[i]<a[i-1]){
			a[0]=a[i];//设置监视哨
			a[i]=a[i-1];//将i-1往后移
			int j;
			for(j=i-2;a[0]<a[j];j--){//从后往前比较
				a[j+1]=a[j]; 
			}
			a[j+1]=a[0];//只有a[j]大于a[0]时,才会跳出循环,所以j+1的位置是a[0]要插入的位置 
		}
	}
}
void output(int a[],int length){
	for(int i=1;i<=length;i++)
		cout<<a[i]<<" ";
	cout<<endl;
} 

折半插入排序

  • 基本思想: 利用折半查找,在a[1…i-1]有的序列中查找a[i]的插入位置。(因为a[1…i-1]是有序的,所以可以用折半查找)
  • 算法分析: 是一种稳定的排序方法,虽然比较次数减小了,但是移动次数不变,所以时间复杂度仍为O(n2),空间复杂度为O(1)。
#include<iostream>
using namespace std;
void Sort_Binsert(int a[],int length);//直接插入排序 
void output(int a[],int length);//输出
int main(){ 
	int a[6]={-1,3,4,5,2,1};
	Sort_Binsert(a,5); 
	output(a,5);
}
void Sort_Binsert(int a[],int length){
	for(int i=2;i<=length;i++){
		a[0]=a[i];//设置监视哨
		int low=1,high=i-1;
		while(low<=high){//只有一个元素的时候也要进行比较,来确定插在这个元素的前面还是后面 
			int mid=(low+high)/2;
			if(a[0]<a[mid])
				high=mid-1;
			else
				low=mid+1;
		}
		for(int j=i-1;j>=low;j--)
			a[j+1]=a[j];
		a[low]=a[0];
	}
}
void output(int a[],int length){
	for(int i=1;i<=length;i++)
		cout<<a[i]<<" ";
	cout<<endl;
} 

希尔排序

  • 希尔排序: 又称缩小增量排序,是基于若待排序的序列为“正序”时,其时间复杂度为O(n),仅需要比较,不需要移动。所以对于一个基本有序的序列,采用希尔排序比较快。
  • 基本思想: 将一个待排序的序列,分为若干个子序列然后分别进行直接插入排序,然后最后对全体进行一次直接插入排序。即先宏观调整,在微观调整
  • 基本算法: 对于一个序列每个元素与相隔dk的元素进行比较。通过改变dk的值进行微调。要注意,dk的值每次应该是递减的,但最后一次一定是1,而且应该是dk增量中的值没有除了1之外的公因子。(即dk中的值不能有公因数
    在这里插入图片描述
#include<iostream>
using namespace std;
void Shell_Insert(int a[],int length,int dk);//希尔插入比较
void Shell_Sort(int a[],int length,int dk[],int dk_len);//希尔排序
void output(int a[],int length);//输出 
int main(){
	int a[6]={-1,3,4,5,2,1};
	int dk[3]={-1,3,1};
	Shell_Sort(a,5,dk,2);
	output(a,5); 
}
void Shell_Insert(int a[],int length,int dk){
	for(int i=1+dk;i<=length;i++){
		if(a[i]<a[i-dk]){
			a[0]=a[i];
			int j;
			for(j=i-dk;j>0&&a[j]>a[0];j-=dk)
				a[j+dk]=a[j];
			a[j+dk]=a[0];
		}
	}
}
void Shell_Sort(int a[],int length,int dk[],int dk_len){
	for(int i=1;i<=dk_len;i++)
		Shell_Insert(a,length,dk[i]);
}
void output(int a[],int length){
	for(int i=1;i<=length;i++)
		cout<<a[i]<<" ";
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值