• 希尔排序


    测试样例:

    49 38 65 97 26 13 27 49 55 4
    

    输出样例:

    49 38 65 97 26 13 27 49 55 4
    ——————————
    13 38 65 97 26 49 27 49 55 4
    13 27 65 97 26 49 38 49 55 4
    13 27 49 97 26 49 38 65 55 4
    13 27 49 55 26 49 38 65 97 4
    13 27 49 55 4 49 38 65 97 26
    ——————————
    13 27 49 55 4 49 38 65 97 26
    4 27 13 55 49 49 38 65 97 26
    4 27 13 55 38 49 49 65 97 26
    4 27 13 55 38 49 49 65 97 26
    4 27 13 55 38 49 49 65 97 26
    4 27 13 49 38 55 49 65 97 26
    4 27 13 49 38 55 49 65 97 26
    4 26 13 27 38 49 49 55 97 65
    ——————————
    4 26 13 27 38 49 49 55 97 65
    4 13 26 27 38 49 49 55 97 65
    4 13 26 27 38 49 49 55 97 65
    4 13 26 27 38 49 49 55 97 65
    4 13 26 27 38 49 49 55 97 65
    4 13 26 27 38 49 49 55 97 65
    4 13 26 27 38 49 49 55 97 65
    4 13 26 27 38 49 49 55 97 65
    4 13 26 27 38 49 49 55 65 97
    ——————————
    4 13 26 27 38 49 49 55 65 97
    

    定义:

    希尔排序的实质就是分组插入排序,该方法又称缩小增量排序

    定义代码:

    void shellsort1(int a[], int n)
    {
    	int i, j, gap;
     
    	for (gap = n / 2; gap > 0; gap /= 2) //步长
    		for (i = 0; i < gap; i++)        //直接插入排序
    		{
    			for (j = i + gap; j < n; j += gap) 
    				if (a[j] < a[j - gap])
    				{
    					int temp = a[j];
    					int k = j - gap;
    					while (k >= 0 && a[k] > temp)
    					{
    						a[k + gap] = a[k];
    						k -= gap;
    					}
    					a[k + gap] = temp;
    				}
    		}
    }
    

    很明显,上面的shellsort1代码虽然对直观的理解希尔排序有帮助,但代码量太大了,不够简洁清晰。因此进行下改进和优化,以第二次排序为例,原来是每次从1A到1E,从2A到2E,可以改成从1B开始,先和1A比较,然后取2B与2A比较,再取1C与前面自己组内的数据比较…….。这种每次从数组第gap个元素开始,每个元素与自己组内的数据进行直接插入排序显然也是正确的。

    改进代码:

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

    再将直接插入排序部分用 经典算法——插入排序 中直接插入排序的第三种方法来改写下:

    改进代码:

    void shellsort3(int a[], int n)
    {
    	int i, j, gap;
     
    	for (gap = n / 2; gap > 0; gap /= 2)
    		for (i = gap; i < n; i++)
    			for (j = i - gap; j >= 0 && a[j] > a[j + gap]; j -= gap)
    				Swap(a[j], a[j + gap]);
    }
  • 相关阅读:
    连号区间数|2013年蓝桥杯B组题解析第十题-fishers
    带分数|2013年蓝桥杯B组题解析第九题-fishers
    翻硬币|2013年蓝桥杯B组题解析第八题-fishers
    错误票据|2013年蓝桥杯B组题解析第七题-fishers
    三部排序|2013年蓝桥杯B组题解析第六题-fishers
    前缀判断|2013年蓝桥杯B组题解析第五题-fishers
    黄金连分数|2013年蓝桥杯B组题解析第四题-fishers
    第39级台阶|2013年蓝桥杯B组题解析第三题-fishers
    马虎的算式|2013年蓝桥杯B组题解析第二题-fishers
    高斯日记|2013年蓝桥杯B组题解析第一题-fishers
  • 原文地址:https://www.cnblogs.com/JingWenxing/p/10111031.html
Copyright © 2020-2023  润新知