算法导论复习与实践(一):插入排序

是否拥有扎实的算法知识和技术基础,是区分真正熟练的程序员与新手的一项重要特征。虽然利用当代的计算技术,无需了解很多算法方面的知识,也可以完成一些任务,但是如果有良好的算法基础和背景的话可以做更多的事情,并且拥有更强的思维能力。学生时期虽然全面学习过算法导论里的相关知识,但是学生时没有太多的编程经验,实践算法时候需要边看书上的伪代码边写程序才能实现,经过工作几年,很多知识已经不记得了。现在想重新拿起,因此将实践过程做些记录方便加深理解与记忆。

插入排序

以我们玩扑克牌时摸牌过程可以非常形象地理解插入排序,我们每从牌堆里摸起一张牌,边从右往左比较每张排的大小,然后将当前的牌插入到第一张比它小的牌后面,这样的排序过程保证手里的牌总是排好序。

下图是书中形象地介绍插入排序实现过程:
插入排序过程从第2个数开始遍历输入数组,图中深黑色部分为每趟排序过程的“当前牌”,将“当前牌”逐个与前面灰色元素的数值比较,如果该数值比“当前牌大”,则将该元素往后移动一个位置,直到找到第一个比“当前牌”小的元素,然后将“当前牌”插入到该元素的后面。
在这里插入图片描述
插入排序C++实现:
插入排序最坏情况是输入数据为逆序的时候,这时候每趟排序,“当前牌”都需要与前面所有的元素进行比较,时间复杂度为:
在这里插入图片描述
我实践中对100万个逆序的输入数据进行排序,需要时间为1143.4秒

#include <sys/time.h>
#include <iostream>
#include <fstream>

void InsertionSort(double* data, const int len)
{
  assert( data != NULL );
  double key = 0.0;
  for( int j = 1; j < len; ++j)
  {
    key = data[ j ];
    int i = j - 1;
    while ( (i >= 0) && ( data [ i ] > key ) )
    {
      data[ i + 1 ] = data[ i ];
      --i;
    }
    data[ i + 1 ] = key;
  }
}
int main()
{

  int len = 1000000;
  double* data = new double[ len ];
  for( int i = len, j = 0; i > 0 && j < len; --i, ++j){
    data[ j ] = i;
  }
  
  struct timeval time_start, time_end;
  gettimeofday(&time_start, NULL);

  //1000000 Time : 1143.4 (s)
  InsertionSort( data , len);
  
  gettimeofday(&time_end, NULL);
  double time = 1000000 *(time_end.tv_sec -time_start.tv_sec) +
           (time_end.tv_usec -time_start.tv_usec);
  time /= 1000000;
  std::cout<<"Time : "<<time<<" (s) "<<std::endl;

  delete []data;
  return 0;
}

猜你喜欢

转载自blog.csdn.net/Sandy_WYM_/article/details/88876515