排序算法总结

1. 插入排序

1.1 基本思想


有N个数据data[N],从头到尾扫描数据data[i],将数据data[i]插入到前面已经排好序的data[0] — data[i-1]的合适位置处,即完成data[0] — data[i]的数据排序,直到数据末尾,结束排序。

1.2 分类


根据确定插入位置时选择的方法不同,可以分为直接插入排序二分(折半)插入排序希尔排序

1.2.1 直接插入排序

基本思想

在确定插入位置时,利用顺序法确定插入位置。

代码实现

template<typename RanIt, typename Pr>
void InsertSort(const RanIt first, const RanIt last, Pr pred) {
   

	typedef typename std::iterator_traits<RanIt>::value_type ValueType;
	typedef typename std::iterator_traits<RanIt>::difference_type DiffType;

	DiffType maxDiff = last - first;

	for (DiffType i = 1; i < maxDiff; ++i) {
   
		ValueType current = *(first + i);
		DiffType j = i - 1;
		for (; j >= 0 && pred(current, *(first + j)); --j) {
   
			*(first + j + 1) = *(first + j);
		}
		*(first + 1 + j) = current;
	}
}

template<typename RanIt>
void InsertSort(const RanIt first, const RanIt last) {
   

	InsertSort(first, last, std::less<>());
}

性能分析

  • 当所要比较的数据已经是排好序时,为该算法最好情况。时间复杂度 O(n)。
  • 当所要比较的数据是逆序排好序时,为算法最差情况。时间复杂度 O(n2)。
  • 原始数据越接近有序,排序速度越快
  • 时间复杂度:min = O(n); max = O(n2); ave = O(n2)
  • 空间复杂度:O(1),需要一个哨兵位置,原地排序。
  • 是一种稳定的排序方法。

1.2.2 二分(折半)插入排序

基本思想

  • 在确定插入位置时,利用二分法确定插入位置。

代码实现

template<typename RanIt, typename Pr>
void binarySearchSort(RanIt first, RanIt last, Pr pred){
   
	typedef typename std::iterator_traits<RanIt>::value_type ValueType;
	typedef typename std::iterator_traits<RanIt>::difference_type DiffType;

	DiffType maxDiff = last - first;
	for (DiffType i = 1; i < maxDiff; ++i){
   
		ValueType current = *(first + i);
		DiffType left = 0, right = i - 1, mid;

		//binary search
		while (left <= right){
   
			mid = (left + right) / 2;
			if(pred(*(first + mid), current)){
   
				left = mid + 1;
			}
			else{
   
				right = mid - 1;
			}
		}

		for(DiffType j = i - 1; j >= left; --j){
   
			*(first + 1 + j) = *(first + j);
		}
		*(first + left) = current;
	}
}

template<typename RanIt>
void binarySearchSort(RanIt first, RanIt last){
   
	binarySearchSort(first, last, std::less<>());
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值