zoukankan      html  css  js  c++  java
  • 希尔排序

    希尔排序

     希尔排序是一种基于插入排序的排序算法,对于大规模乱序数组的排序,插入排序很慢,因为它志辉交换相邻的元素,因此元素只能一点一点地从数组的一端移动到另一端。假设,数组中最小的数正好在数组的尽头,要将它移动到适合的位置就要进行N-1次移动。希尔排序为了加快速度简单地改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。

    希尔排序的思想是:先将整个待排序的数组分割成若干个等长的子序列分别进行插入排序,使得若干子数组称为递增序列,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小),再对全体元素进行依次插入排序,因为插入排序在元素基本有序的情况下,效率是最高的。

    假设有7个元素的数组,1  10  -5  9  8  7  3,现在要对他们进行希尔排序,图1-1展示了对数组希尔排序的步骤,在排序时,每段等长的数组会进行插入排序,当arr[i]<arr[i-step]时,替换两个位置上的元素,再检查arr[i-step]和arr[i-2*step],如果arr[i-step]<arr[i-2*step],再接着替换两个位置上的元素,以此类推,直到arr[i-n*step]>arr[i-(n+1)*step]

    图1-1

    由于希尔排序的时间复杂度依赖于递增序列,不同的序列时间复杂度不同,因此希尔排序的时间复杂度分析还是一个待解决的问题。

    代码1-2为希尔排序的C语言实现

    #include <stdio.h>
    
    void shell_sort( int arr[], int len );
    
    
    void shell_sort( int arr[], int len )
    {
    	int	step	= len;
    	int	i	= 0, j = 0, temp = 0;
    	while ( 1 )
    	{
    		step /= 2;
    		for ( i = step; i < len; i++ )
    		{
    			for ( j = i; j >= step && arr[j] < arr[j - step]; j -= step )
    			{
    				temp		= arr[j];
    				arr[j]		= arr[j - step];
    				arr[j - step]	= temp;
    			}
    		}
    		if ( step == 1 )
    		{
    			break;
    		}
    	}
    }
    
    
    void main()
    {
    	int	i	= 0;
    	int	arr[]	= { 1, 10, -5, 9, 8, 7, 3 };
    	int	len	= sizeof(arr) / sizeof(arr[0]);
    	printf( "待排序数组:" );
    	for ( i = 0; i < len; i++ )
    	{
    		printf( "%d ", arr[i] );
    	}
    	printf( "
    " );
    	shell_sort( arr, len );
    	printf( "排序后数组:" );
    	for ( i = 0; i < len; i++ )
    	{
    		printf( "%d ", arr[i] );
    	}
    }
    

      

    代码1-3为希尔排序的Java实现

    import java.util.Arrays;
    
    public class Shell {
    
    	public static void shellSort(int... arr) {
    		int step = arr.length;
    		while (true) {
    			step = (int)Math.ceil(step/2);
    			for (int i = step; i < arr.length; i++) {
    				for (int j = i; j >= step && arr[j] < arr[j - step]; j -= step) {
    					int temp = arr[j];
    					arr[j] = arr[j - step];
    					arr[j - step] = temp;
    				}
    			}
    			if(step == 1){
    				break;
    			}
    		}
    	}
    
    	public static void main(String[] args) {
    		int[] arr = { 1, 10, -5, 9, 8, 7, 3};
    		System.out.print("待排序数组:" + Arrays.toString(arr));
    		System.out.println();
    		shellSort(arr);
    		System.out.println("排序后数组:" + Arrays.toString(arr));
    	}
    
    }
    

      

     代码1-4为希尔排序的Python实现

    # coding:utf-8
    def shell_sort(arr):
        step = len(arr)
        while True:
            step /= 2;
            for i in range(step, len(arr)):
                j = i
                while j >= step and arr[j] < arr[j - step]:
                    temp = arr[j]
                    arr[j] = arr[j - step]
                    arr[j - step] = temp
                    j -= step
            if step == 1:
                break
    
    
    arr = [1, 10, -5, 9, 8, 7, 3]
    print "待排序数组:", arr
    shell_sort(arr)
    print "排序后数组", arr
    

      

    代码1-5为希尔排序的Scala实现

    import java.util.Arrays
    
    object Shell {
    
      def shellSort(comparator: (Int, Int) => Boolean)(arr: Array[Int]) {
        var step = arr.length
        while (step != 0) {
          for (i <- step until arr.length) {
            var j = i
            while (j >= step && comparator(arr(j - step), arr(j))) {
              var temp = arr(j)
              arr(j) = arr(j - step)
              arr(j - step) = temp
              j -= step
            }
          }
          step /= 2
        }
      }
      def main(args: Array[String]): Unit = {
        val arr = Array(1, 10, -5, 9, 8, 7, 3)
        println("待排序数组:" + Arrays.toString(arr))
        shellSort(_ > _)(arr)
        println("排序后数组:" + Arrays.toString(arr))
      }
    }
    

      

  • 相关阅读:
    一个小笔记(5):A*算法
    一个小笔记(4):递归下降分析法
    1.3 初步了解信号和槽
    一个小笔记(3):约瑟夫环
    1.2 第一个程序
    requestAnimationFrame
    javascript reg 不加入分组
    正则表达式匹配除单词外的任何字符
    自動化ツール(コード生成、パターン抽出)
    windows常用DLL及作用
  • 原文地址:https://www.cnblogs.com/fuxinyue/p/6918276.html
Copyright © 2011-2022 走看看