/**
* Copyright (C) 2015, CSU
* All rights reserved
* File Name:test.cpp
* Author: lmm
* Date of completion: 2015/1/20
* Version: v1.0
*
* 问题描述:希尔排序
* 输入描述: 输入整数
* 知识点 : 内部排序
* 程序输出: 输出有序整数
*/
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
void ShellInsert(int *seqList,int length,int dk)
{
int i,j;
// seqList[0]只是暂存单元
for(i = dk + 1; i < length; ++i) // 同增量
{
if(seqList[i] < seqList[i-dk]) // 当前记录与前dk的记录比较
{
seqList[0] = seqList[i]; // seqList[0]暂存当前的记录,比较后寻找正确的位置插入,每个增量比较后都会插入到此趟的正确位置上
for(j = i - dk; j > 0 && seqList[0] < seqList[j]; j-=dk) // 同增量循环两两比较 这个地方需要注意
{
seqList[j+dk] = seqList[j]; // 这个地方需要注意 seqList[j+dk]存放的是seqList[j]的记录,而seqList[j]还是原来的记录
}
seqList[j+dk] = seqList[0];
// 若是j<0 seqList[j+dk]即为seqList[1],由于循环条件中执行j-=dk,使得j<0;故将j+dk回到原来数值,最小也为1.将seqList[0]暂存的记录放入seqList[1]中
// 若是seqList[0]>seqList[j],循环终止,本身j已减去dk,j+dk将回到之前的j处,将seqList[0]放入此处.
}
}
}
void ShellSort(int *seqList,int data[], int t,int length)
{
for(int k = 0; k < t; ++k) // 循环每一个增量,进行同增量跳跃式排序
ShellInsert(seqList,length,data[k]); // 希尔插入排序
}
int main()
{
int a[11] = {0};
int result[10] = {0};
int data[3] = {5,2,1};
int seqNum = 0;
cout << "Input ten numbers: ";
for (int i = 1; i < 11; ++i) // 输入10个数,result[0]为哨兵
{
cin >> seqNum;
a[i] = seqNum;
}
double dLen = 10;
int nLen = 0;
for(int i = 0; dLen >1; ++nLen,++i)
{
dLen = dLen/2;
data[i] = dLen;
}
// nLen 是data数组的长度 dLen是增量
ShellSort(a,data,nLen,11); // 希尔排序
cout << endl << "Output the results: ";
for (int j = 0, i = 1; j < 10 && i < 11; ++i,++j)
{
result[j] = a[i];
cout << result[j] << " ";
}
cout << endl;
return 0;
}
总结:希尔排序的增量取法不一,d=d/2有的向上取整,有的向下取整。但需注意:应使增量序列中的值没有除1之外的公因子,并且最后一个增量值必须等于1.
希尔排序的时间复杂度为.当n在某个特定范围内,希尔排序所需的比较次数和移动次数约为,当,可减少到.