希尔排序:
希尔排序又叫做增量递减排序,他的基本思想是:假设待排序元素有n个,a1,a2,a3,a4,a5,a6,a7,a8,a9,...,设增量为4的元素为同一个子序列,即a1,a5,a9,a13...,同理,a2,a6,a10,a14...等,然后对同一个子序列内的元素进行直接插入排序,之后,缩小增量为2,即a1,a3,a5,a7...,a2,a4,a6,a8...,对同一个子序列内的元素进行直接插入排序,最后,令增量为1,这是之后一个子序列,对整个元素进行排序。
实现代码:(C#实现)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
int[] a = new int[] { 45, 23, 56, 12, 97, 76, 29, 68 };//待排序数组
Console.WriteLine("进行几次希尔排序:");
int i =Convert.ToInt32( System.Console.ReadLine());
for (int j = 0; j < i; j++) {
Console.WriteLine("第"+(j+1)+"次的增量为:");
int m =Convert.ToInt32(System.Console.ReadLine());
ShellInsert(m,a);
}
}
static void ShellInsert(int c,int[]b) {
for(int i=c;i<b.Length;i++){//遍历从索引为增量开始之后的数组,让之后的每个数组元素都和它自身的索引减去增量后的所得到的索引相对应的元素相比较
if(b[i]<b[i-c]){//如果后者小于前者,要移动前者
int t=b[i];//记录下后者
int j;
for(j=i-c;j>-1&&t<b[j];j-=c){
b[j+c]=b[j];
}
b[j+c]=t;
}
}
for (int i = 0; i < b.Length; i++)
{
Console.WriteLine(b[i]);
}
Console.ReadKey();
}
}
}
总共进行3次排序,第一次增量为3时,结果为:
第二次增量为2时,结果为:
第三次增量为1时,结果为:
最后一次进行的排序就是直接插入排序,但是前两次的铺垫让整个数组有些顺序了,直接插入排序算法的时间复杂度在最好的情况下就是所有元素已经有序,希尔排序算法的时间复杂度为O(n^3/2),因为希尔排序按照增量对每个子序列进行排序,有可能两个相等的元素在分别处于不同的序列中,造成排序过程中两者顺序颠倒,所以希尔排序是不稳定的排序算法。