为什么我的Shell排序这么慢?

时间:2014-02-28 20:28:24

标签: javascript algorithm performance sorting shellsort

我正在尝试在JavaScript中实现一堆排序算法,我无法弄清楚为什么我的shell排序太慢了。它比我的合并排序慢6倍,并且只比我的插入排序稍快。我已经在网上看到了另一个实现,但我更专注于使它清晰可读(因为我有一个博客的新手),更快的实现对我的目的来说太简洁了。关于如何保持总体规划但让它更快地移动的任何想法?

  var shellSort = function( list ) {
    var gapSize = Math.floor( list.length / 2 );

    while( gapSize > 0 ) {
      _shellInsertionSort( list, gapSize );
      gapSize = Math.floor( gapSize / 2 );
    }

    return list;
  };

  function _shellInsertionSort( list, gapSize ) {
    var temp, i, j;

    for( i = gapSize; i < list.length; i += gapSize ) {
      j = i;
      while( j > 0 && list[ j - gapSize ] > list[j] ) {
        temp = list[j];
        list[j] = list[ j - gapSize ];
        list[ j - gapSize ] = temp;
        j -= gapSize;
      }
    }
  };

我的合并排序:

  var mergeSort = function( list ) {
    if ( list.length <= 1 ) {
      return list;
    }

    var left = [],
        right = [],
        middle = Math.floor( list.length / 2 ),
        i;

    for( i = 0; i < middle; i++ ) {
      left.push( list[i] );
    }

    for( ; i < list.length; i++ ) {
      right.push( list[i] );
    }

    left = mergeSort( left );
    right = mergeSort( right );

    return _merge( left, right );
  };

  function _merge( left, right ) {
    var result = [];

    // Should be able to just get rid of arguments in while loop
    while( left.length || right.length ) {
      if( left.length > 0 && right.length > 0 ) {
        if( left[0] <= right[0] ) {
          result.push( left.shift() );
        } else {
          result.push( right.shift() );
        }
      } 
      else if( left.length ) {
        return result.concat( left );
      } 
      else {
        return result.concat( right );
      }
    }
  }

我的测试:

  var testSpeed = function( testSize, rounds ) {
    var testArrays = [],
        algorithms = Array.prototype.slice.call( arguments, 2 ),
        results = [],
        i, j;

    for( i = 0; i < rounds; i++ ) {
      testArrays[i] = [];
      for( j = 0; j < testSize; j++ ) {
        testArrays[i].push( Math.ceil( Math.random() * testSize ));
      }
    }

    for( i = 0; i < algorithms.length; i++ ) {
      for( j = 0; j < rounds; j++ ) {
        if( !results[i] ) {
          results[i] = [];
        }
        results[i].push( testAlgorithm( algorithms[i], testArrays[j] ));
      }
    }

    return results;
  };

  var testAlgorithm = function( algorithm, set ) {
    var clone = set.slice(),
        start = new Date().getTime(),
        end;

    algorithm( clone );

    end = new Date().getTime();

    return end - start;
  };

1 个答案:

答案 0 :(得分:1)

我把你的算法放在一起,制作了一个简单的样本,记录时间(用millis()而不是你测试它我不理解的方式)并输出平均时间。对于100个数字的数组,Shell排序为0.02毫秒。没有考虑到大多数毫秒级记录都采用shell排序(因为它有时为0)。我使用合并排序做了同样的事情,并且它的时间为0.21毫秒..希望这可以回答https://www.khanacademy.org/computer-programming/sort-algorithms/6199294078746624