经典算法之Shell排序及其优化

希尔排序的具体分析见http://blog.csdn.net/morewindows/article/details/6668714/

/************************
author's email:wardseptember@gmail.com
date:2017.12.11
希尔排序
************************/
#include<iostream>
#define maxSize 10
using namespace std;
void shellSort1(int *a, int n);
void shellSort2(int *a, int n);
void Swap(int &a, int &b);//交换函数
void shellSort3(int *a, int n);
void printArray(int D[], int n);
void main() {
	int D[maxSize] = { 12,15,48,46,16,78,57,88,65,48 };//构造一个一维数组
	int E[maxSize] = { 12,15,48,46,16,78,57,88,65,48 };
	int F[maxSize] = { 12,15,48,46,16,78,57,88,65,48 };

	shellSort1(D, maxSize);
	cout << "希尔排序第一种算法结果为:" << endl;
	printArray(D, maxSize);


	shellSort2(E, maxSize);
	cout << "希尔排序第二种算法结果为:" << endl;
	printArray(E, maxSize);


	shellSort3(F, maxSize);
	cout << "希尔排序第三种算法结果为:" << endl;
	printArray(F, maxSize);
}
void shellSort1(int *a, int n) {
	int i, j;
	int inc;//代表增量
	for(inc=n/2;inc>0;inc/=2)//希尔排序的增量选择都是从n/2开始,每次再减半,直到最后为1
		for (i = 0; i < inc; ++i) {//直接插入排序的应用,每一组组内进行排序,可与直接插入排序算法对比理解
			for(j=i+inc;j<n;j+=inc)//每次增加inc。用于找到这些元素
				if (a[j] < a[j - inc]) {/*在循环刚开始时加上一句判断,若a[j]>=a[i-inc]说明a[0...j]本身就是有序的,无需调整,否则按就调整。*/
					int temp = a[j];
					int k = j - inc;
					while (k >= 0 && a[k] > temp) {//找到要插入的位置,并将a[k+inc]前面的数后移
						a[k + inc] = a[k];
						k -= inc;
					}
					a[k + inc] = temp;//因为最后k减一个temp,所以这里加一个
				}
		}
}

/*对比第一种方法可以发现,第二种方法少了一层循环,可以理解为把两个循环合并为一个循环
,两种方法都是每组组内进行直接插入排序,遍历完所有元素即可。显而易见,从时间复杂度上来看,第二种方法更简单
*/
void shellSort2(int *a, int n)
{
	int j, inc;//inc代表增量

	for (inc = n / 2; inc > 0; inc /= 2)
		for (j = inc; j < n; j++)//从数组第gap个元素开始  
			if (a[j] < a[j - inc])//每个元素与自己组内的数据进行直接插入排序  
			{
				int temp = a[j];
				int k = j - inc;
				while (k >= 0 && a[k] > temp)
				{
					a[k + inc] = a[k];
					k -= inc;
				}
				a[k + inc] = temp;
			}
}


void Swap(int &a, int &b) //引用类型方式  
{
	int temp; //辅助变量  
	temp = a;
	a = b;
	b = temp;
}
/*
第三种方法是用元素交换的方法代替数组后移
*/
void shellSort3(int *a, int n)
{
	int i, j, inc;

	for (inc = n / 2; inc > 0; inc /= 2)
		for (i = inc; i < n; i++)
			for (j = i - inc; j >= 0 && a[j] > a[j + inc]; j -= inc)//将前面两种方法的几句代码,合并为一句。对比理解
				Swap(a[j], a[j + inc]);
}
void printArray(int D[], int n) {
	for (int i = 0; i < n; ++i)  //输出排序后的关键字
		cout << D[i] << " ";
	cout << endl;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值