【算法导论】插入排序实现

#ifndef INSERTION_SORT_H
#define INSERTION_SORT_H

#include <iterator>

//
// 插入排序:
//	 最坏情况:逆序数组 cn^2 + n = n^2 + n
//	 一般情况:n(n-1)/2 = n^2 - n
//	 最好情况:已经排好序的数组 cn
//	 如果用户经常遇到上面的最坏情况,我们稍微做了一些优化
//	 使用smart_insertion_sort会稍微加快速度,但是如果并不是经常
//	 遇到,还是不要用smart比较好
//
template <typename Iterator>
void smart_insertion_sort(Iterator first, Iterator last)
{
	// 如果成立,那么很可能是正向排序情况比较多的
	if (*first < *last)
	{
		insertion_sort(first, last);
	}
	// 如果不成立,那么很可能是反向排序情况比较多的
	else
	{
		reverse_insertion_sort(first, last);
		// 这时再将数组反转
		reverse(first, last);
	}
}

// 我们假设从小到大排列是默认的正向排列
template <typename Iterator>
void insertion_sort(Iterator first, Iterator last)
{
	// 用到了一点template编程的技巧
	insertion_sort_aux(first, last, std::_Val_type(first));	
}

template <typename Iterator, typename T>
void insertion_sort_aux(Iterator first, Iterator last, T*)
{
	/************************************************************************/
	/* 
		算法思维方式:
			从第二个位置开始向后遍历整个数组
			从每个遍历的位置开始
			往前遍历已经排好序的部分
			使得这个位置也成为已经排好序的部分
	*/
	/************************************************************************/
	for (Iterator iter = first + 1; iter != last; ++iter)
	{
		for (Iterator cur = iter; cur != first; --cur)
		{
			if (*(cur - 1) > *cur)
			{
				T tmp = *cur;
				*cur = *(cur - 1);
				*(cur - 1) = tmp;
			}
		}
	}
	/************************************************************************/
	/* 
		(循环不变式)loop invariant:
			初始化:i是2,左边是1,只有一个元素,显然是排好序的
			保持:对于每个i,总要找到第一个比自己小的元素,并放在它的右边,而对于左边的所有元素
				 都是排好序的,所以每次遍历都能保证被遍历的元素排序了
			终止:i终止于length[Array]+1,而因为i左边的元素都是排好序的,所以数组被排好序了
	*/
	/************************************************************************/
}

// 因为我们假设从小到大排序是正向,所以从大到小是反向
template <typename Iterator>
void reverse_insertion_sort(Iterator first, Iterator last)
{
	reverse_insertion_sort_aux(first, last, std::_Val_type(first));
}

template <typename Iterator, typename T>
void reverse_insertion_sort_aux(Iterator first, Iterator last, T*)
{
	/************************************************************************/
	/* 
		算法原理:
			同上
	*/
	/************************************************************************/

	for (Iterator iter = first + 1; iter != last; ++iter)
	{
		for (Iterator cur = iter; cur != first; --cur)
		{
			if (*(cur - 1) < *cur)
			{
				T tmp = *cur;
				*cur = *(cur - 1);
				*(cur - 1) = tmp;
			}
		}
	}
	
	/************************************************************************/
	/* 
		loop invariant:
			同上
	*/
	/************************************************************************/
}

#endif // INSRTION_SORT_H


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值