插入排序—希尔排序

本文对于希尔排序的实现有两种细节不同的方式:


希尔排序中的部分代码和直接插入排序类似,直接插入排序是增量d为1的特例。
直接插入排序跳转

区分子列单独处理
void shellSort1(int a[],int n){
	//设置起始增量为数组长度的一半
	for(d=n/2;d>=1;d/=2){
		//m为子列的数量 
		if(n%d==0){
			m=n/d;
		}
		else{
			m=n/d+1;
		}
		//wh确定当前操作的是第几个子列 
		for(wh=0;wh<m;wh++){
			//这里i的初值是当前子列中的第二个元素 
			//i每次+d,在同一个子列操作 
			for(i=d+wh;i<n;i+=d){
				//往后和直接插入排序是一样的,只是直接插入排序中d为1 
				if(a[i]<a[i-d]){
					temp=a[i];
					for(j=i-d;j>=0&&a[j]>temp;j-=d){
						a[j+d]=a[j];
					}
					a[j+d]=temp;
				} 
			}
		}
	}
} 
按数组顺序轮流子列处理
void shellSort2(int a[],int n){
	for(d=n/2;d>=1;d/=2){
		//注意对比,这里的i每次+1,是不区分子列,依次对数组进行排序 
		for(i=d;i<n;i++){
			if(a[i]<a[i-d]){
				temp=a[i];
				for(j=i-d;j>=0&&a[j]>temp;j-=d){
					a[j+d]=a[j];
				}
				a[j+d]=temp;
			} 
		}
	}
} 

运行代码

//设置不同的增量,排序趟数以及在每趟中各个元素对比和移动次数也不同
//最坏时间复杂度:O(n^2),当n在某个范围内,可达O(n^1.3) 
//不稳定排序算法,仅适用于顺序表
#include <iostream>
using namespace std;
int i,j;
int temp;	//存放当前元素
int d;		//增量 
int m;		//以当前增量作为分割,m为子列的数量
int wh; 	//wh确定当前操作的是第几个子列 

//这里的是单独对每个子列进行操作 
void shellSort1(int a[],int n){
	//设置起始增量为数组长度的一半
	for(d=n/2;d>=1;d/=2){
		//m为子列的数量 
		if(n%d==0){
			m=n/d;
		}
		else{
			m=n/d+1;
		}
		//wh确定当前操作的是第几个子列 
		for(wh=0;wh<m;wh++){
			//这里i的初值是当前子列中的第二个元素 
			//i每次+d,在同一个子列操作 
			for(i=d+wh;i<n;i+=d){
				//往后和直接插入排序是一样的,只是直接插入排序中d为1 
				if(a[i]<a[i-d]){
					temp=a[i];
					for(j=i-d;j>=0&&a[j]>temp;j-=d){
						a[j+d]=a[j];
					}
					a[j+d]=temp;
				} 
			}
		}
	}
} 

//这里是依次对数组元素操作,不分是哪个子列 
void shellSort2(int a[],int n){
	for(d=n/2;d>=1;d/=2){
		//注意对比,这里的i每次+1,是不区分子列,依次对数组进行排序 
		for(i=d;i<n;i++){
			if(a[i]<a[i-d]){
				temp=a[i];
				for(j=i-d;j>=0&&a[j]>temp;j-=d){
					a[j+d]=a[j];
				}
				a[j+d]=temp;
			} 
		}
	}
} 

//输出
void out(int a[],int n){
	for(int i=0;i<n;i++){
		cout<<a[i]<<" ";
	} 
}
int main(){
	int a[]={53,13,29,1,5,99,76,38};
	int n=sizeof(a)/sizeof(int);
	shellSort2(a,n);
	out(a,n);
	
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值