算法系列之——希尔排序算法
2015-03-19 15:22
113 查看
一、希尔排序
技术要点:现将整个待排序记录序列分隔成若干个子序列分别进行插入排序,待整个序列中的记录“基本有序”的时候再对全体记录进行一次直接插入排序。
例子:[7 9 10 5 11 6 ]进行希尔排序
步骤:
1.首先进行关键字的选取(排序的关键)如选取3和1(第一步分成3组,第二部分成1组)下面先分成3组
2.[7,5] [9,11] [10,6] 三个组(不是临近的数字组成一组,而是3的倍数+1组成一组),这3个组是为达到分析的目的进行的虚拟分组
3.对上面3组分别进行插入排序得到[5,7] [9,11] [6,10] 三个数组
4.因此第一趟排序后的结果为:[7 9 10 5 11 6 ]—》[5 9 7 6 11 10 ]
5.进行第二趟,关键字选取1组,参考步骤1 此时待排数组为[5 9 7 6 11 10 ]
6.对待排数组进行插入排序
7.对于关键字的判断选择一般情况下如果是10个的话 选择 10 3 1 其他情况需要判断
希尔算法可以看作是改进的直接插入算法,其算法的性能与所选取的分组长度序列有很大关系
其时间性能的优势:
①当文件初态基本有序时直接插入排序所需的比较和移动次数均较少。
②当n值较小时,n和
的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0(
)差别不大。
③在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。
二、代码演示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ShellSort //希尔排序算法
{
class Program
{
static void Main(string[] args)
{
int[] arr = { 7, 9, 10, 5, 11, 6 };
Console.WriteLine("未排序的数组");
foreach (var item in arr)
{
Console.Write(item + "\t");
}
Console.WriteLine();
Console.WriteLine("希尔排序后的数组");
shell_sort(arr, 6);
foreach (var item in arr)
{
Console.Write(item + "\t");
}
Console.ReadKey();
}
/// <summary>
///
/// </summary>
/// <param name="unsorted">待排数组</param>
/// <param name="length">数组长度</param>
static void shell_sort(int[] unsorted, int length)
{
int inc, i, j, temp;//inc为关键步长
//假定待排数组有6个,这里关键步长取3和1
for (inc = length / 2; inc > 0; inc = inc / 2) //第一躺:inc=3
{
for (i = inc; i < length; i++) //第一躺:inc=3情况下 i=3;
{
for (j = i - inc; j >= 0; j = j - inc) //第一躺:inc=3情况下 i=3情况下 j=0;
{
{
if (unsorted[j] > unsorted[j + inc]) //第一躺:inc=3情况下 i=3情况下 j=0 情况下 插入排序;
{
temp = unsorted[j];
unsorted[j] = unsorted[j + inc];
unsorted[j + inc] = temp;
}
}
}
}
}
}
}
}
结果演示:
未排序的数组:
7 9 10 5 11 6
希尔排序后的数组:
5 6 7 9 10 11
技术要点:现将整个待排序记录序列分隔成若干个子序列分别进行插入排序,待整个序列中的记录“基本有序”的时候再对全体记录进行一次直接插入排序。
例子:[7 9 10 5 11 6 ]进行希尔排序
步骤:
1.首先进行关键字的选取(排序的关键)如选取3和1(第一步分成3组,第二部分成1组)下面先分成3组
2.[7,5] [9,11] [10,6] 三个组(不是临近的数字组成一组,而是3的倍数+1组成一组),这3个组是为达到分析的目的进行的虚拟分组
3.对上面3组分别进行插入排序得到[5,7] [9,11] [6,10] 三个数组
4.因此第一趟排序后的结果为:[7 9 10 5 11 6 ]—》[5 9 7 6 11 10 ]
5.进行第二趟,关键字选取1组,参考步骤1 此时待排数组为[5 9 7 6 11 10 ]
6.对待排数组进行插入排序
7.对于关键字的判断选择一般情况下如果是10个的话 选择 10 3 1 其他情况需要判断
希尔算法可以看作是改进的直接插入算法,其算法的性能与所选取的分组长度序列有很大关系
其时间性能的优势:
①当文件初态基本有序时直接插入排序所需的比较和移动次数均较少。
②当n值较小时,n和
的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0(
)差别不大。
③在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。
二、代码演示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ShellSort //希尔排序算法
{
class Program
{
static void Main(string[] args)
{
int[] arr = { 7, 9, 10, 5, 11, 6 };
Console.WriteLine("未排序的数组");
foreach (var item in arr)
{
Console.Write(item + "\t");
}
Console.WriteLine();
Console.WriteLine("希尔排序后的数组");
shell_sort(arr, 6);
foreach (var item in arr)
{
Console.Write(item + "\t");
}
Console.ReadKey();
}
/// <summary>
///
/// </summary>
/// <param name="unsorted">待排数组</param>
/// <param name="length">数组长度</param>
static void shell_sort(int[] unsorted, int length)
{
int inc, i, j, temp;//inc为关键步长
//假定待排数组有6个,这里关键步长取3和1
for (inc = length / 2; inc > 0; inc = inc / 2) //第一躺:inc=3
{
for (i = inc; i < length; i++) //第一躺:inc=3情况下 i=3;
{
for (j = i - inc; j >= 0; j = j - inc) //第一躺:inc=3情况下 i=3情况下 j=0;
{
{
if (unsorted[j] > unsorted[j + inc]) //第一躺:inc=3情况下 i=3情况下 j=0 情况下 插入排序;
{
temp = unsorted[j];
unsorted[j] = unsorted[j + inc];
unsorted[j + inc] = temp;
}
}
}
}
}
}
}
}
结果演示:
未排序的数组:
7 9 10 5 11 6
希尔排序后的数组:
5 6 7 9 10 11
相关文章推荐
- 算法系列之--Javascript和Kotlin的希尔排序算法(原)
- >重点算法解疑系列文档·再快一点
- C++算法系列之日历生成的算法代码
- 数据结构与算法(C#实现)系列---演示篇(一)(外摘)
- C/C++面试之算法系列--菲波拉契数列的递归与非递归算法
- BBS 设计思路系列 ---- 网友提供的一个用户在CSDN的总分算法
- C/C++面试之算法系列--如何实现用更少的空间表示英文字母(a ~ z)构成char A[n]字符串
- Google外传系列--PageRank核心算法 ->谈Page Rank Google 的民主表决式
- C/C++面试之算法系列--以单词为最小单位翻转字符串
- C/C++面试之算法系列--约瑟夫环:每隔两个循环删除数组元素,求最后删除者的下标问题
- openssl之EVP系列之1---算法封装
- 20060427-汉字区位码查询与算法——microsoft visual studio 2005系列
- P2P普及系列之七:DHT算法的研究 zz
- 数据结构与算法(C#实现)系列---AVLTree(二)(外摘)
- 算法基础系列之三:螺旋形矩阵
- openssl之EVP系列之7---信息摘要算法结构概述
- >重点算法解疑系列文档·脚踏实地
- (codes)二叉树的系列算法,递归与非递归
- 算法为王--正本溯源系列之一
- java.util.concurrent系列文章--(4)非阻塞算法简介