算法基础-希尔排序

来源:互联网 发布:程序员软件工程师招聘 编辑:程序博客网 时间:2024/06/06 05:24

一、希尔排序

希尔排序,也称也称递减增量排序算法,它是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。【来自维基百科】

   下面直接以一个例子来说明吧!例如,一个数组A={49, 38, 65, 97, 26, 13, 27, 49, 55, 4}为例,个数n=10。

第一次 步长gap= n/2= 10/2 = 5

这样原来的数组可以被划分为{49,13},{38,27},{65,49},{97,55},{26,4}

之后对每个划分以插入排序的形式互换位置,于是有{13,49},{27,38},{49,65},{55,97},{4,26},将这些划分对应到A中的位置(如,13和49互换了位置,38和27互换位置,其实就是这些划分原先的数值位置保持不变,只是在划分的组内部进行位置互换而已),于是这次的排序为:

         A1= {13,27,49,55,4,49,38,65,97,26};

第二次 步长gap = 5/2 = 2

以步长为2对进行A1划分,如从13开始,步长为2进行选择,可以得到{13,49,4,38,97},接着以27开始,步长为2进行选择,可以得到{27,55,49,65,26},接着再从49开始,可是这里的49已经在前面的一个划分中,因此不需要进行了。于是我们就得到了两个划分。接着对这两个划分以插入排序形式排序,于是有{4,13,38,49,97}和{26,27,49,55,65},将它们对应到A1排序后的数值位置,于是有这样的排序:

       A2={4,26,13,27,38,49,49,55,97,65};

第三次 步长gap = 2/2 = 1

以步长为1对A2进行划分,从4开始,步长为1进行选择,可以得到{4,26,13,27,38,49,49,55,97,65},我们发现这是整个组都为一个划分,这样我们对整个数值按插入进行排序,于是有:

       A3={4,13,26,27,38,49,49,55,65,97};

第四次 步长gap = 1/2 = 0,由于gap=0,表示排序已经结束

另外需要注意的是,插入排序又分为:直接插入排序、折半插入排序、2-路插入排序等,在下面的的实现中,我只是使用了直接插入排序!

二、算法实现

// 希尔排序.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>using namespace std;void shellsort(int a[], int n);void Insertsort(int a[], int n, int gap)  ;void print(int a[],int n);void Swap(int *x1, int *x2);int _tmain(int argc, _TCHAR* argv[]){const int N=10;//int Array[N]={1,-1,3,4};int Array[N]= {49 ,38,65 , 97 ,26,13 ,27 ,49 ,55 ,4};//打印输出cout << "原始数据:" << endl;print(Array,N);//排序shellsort(Array,N);//打印输出cout <<"排序后数据:"<< endl;print(Array,N);return 0;}//希尔排序void shellsort(int a[], int n)  {      int i,gap;   int m=1;    for (gap = n / 2; gap > 0; ) //步长  {           for (i = 0; i < gap; i++)               {  //直接插入排序  Insertsort(a, n, gap);          } cout << "gap = " << gap <<"第"<<m<<"次"<<endl;print(a,n);gap = gap/ 2;m++;}} //打印数组void print(int a[], int n){for ( int i=0; i< n; i++)cout << a[i] << " ";cout << endl;}//直接插入排序void Insertsort(int a[], int n, int gap)  //当gap=1的时候,就是通常的直接插入排序(数据间是相邻){        for (int i = gap; i < n; i=i+gap)          if (a[i] < a[i - gap])  //a[i] >= a[i-gap]表示a[0...i-gap]是有序的,无需调整        {              int temp = a[i]; int k=i - gap;            while(k>=0 && a[k] > temp)  {                a[k + gap] = a[k];  k=k-gap;}            a[k + gap] = temp;          }  } void Swap(int *x1, int *x2){int temp;temp = *x1;*x1 = *x2;*x2 = temp;}


运行结果:




0 0
原创粉丝点击