冒泡,选择,堆排序

十大排序算法

你好! 这是你第一次使用 **Markdown编辑器** 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

冒泡排序

在这里插入图片描述
冒泡排序也叫做起泡排序。

执行流程

  • 从头开始比较每一对相邻元素,如果第1个比第2个大,就交换它们的位置。执行完一轮后,最未尾那个元素就是最大的元素。
  • ② 忽略①中曾经找到的最大元素,重复执行步骤①,直到全部元素有序。
    这是一个标准的冒泡排序。
/**
 * 冒泡排序-无优化
 */
public class BubbleSort1<T extends Comparable<T>> extends Sort<T>{
	
	@Override
	protected void sort() {
		for (int end = array.length - 1; end > 0; end--) {
			for (int begin = 1; begin <= end; begin++) {
				if (cmp(begin, begin - 1) < 0) {
					swap(begin, begin - 1);
				}
			}
		}
	}	
}

冒泡排序优化一

此优化不一定有用,只有在有序的情况下时间复杂度更低
这个优化并不会提高冒泡排序的平均性能,只是针对极端条件进行处理。
如果序列已经完全有序,可以提前终止冒泡排序。
在这里插入图片描述

/**
 * 冒泡排序-优化1
 * 如果序列已经完全有序,可以提前终止冒泡排序
 */
public class BubbleSort2<T extends Comparable<T>> extends Sort<T>{
	
	@Override
	protected void sort() {
		for (int end = array.length - 1; end > 0; end--) {
			boolean sorted = true;
			for (int begin = 1; begin <= end; begin++) {
				if (cmp(begin, begin - 1) < 0) {
					swap(begin, begin - 1);
					sorted = false;
				}
			}
			if (sorted) break;
		}
	}
	
}

冒泡排序优化二

这个优化是在优化一的基础上,增大极端条件的范围,从完全有序变为尾部局部有序

如果序列尾部已经局部有序,可以记录最后1次交换的位置,减少比较次数
在这里插入图片描述

/**
 * 冒泡排序-优化2
 * 如果序列尾部已经局部有序,可以记录最后1次交换的位置,减少比较次数
 */
public class BubbleSort3<T extends Comparable<T>> extends Sort<T>{
	
	@Override
	protected void sort() {
		for (int end = array.length - 1; end > 0; end--) {
			// 设为1是因为:如果这轮遍历一次交换都没进行
			// 则说明序列后面已经有序, 则 end = sortedIndex = 1
			// end--后等于0,会直接跳出循环
			int sortedIndex = 1; //为完全有序做准备
			for (int begin = 1; begin <= end; begin++) {
				if (cmp(begin, begin - 1) < 0) {
					swap(begin, begin - 1);
					// 记录最后1次交换的位置,减少比较次数
					sortedIndex = begin;
				}
			}
			end = sortedIndex;
		}
	}
}

复杂度与稳定性

复杂度

在这里插入图片描述
最好时间复杂度:完全有序,只需要经过一趟扫描
在这里插入图片描述

稳定性

在这里插入图片描述
冒泡排序属于 In-place
冒泡排序属于稳定的排序算法
稍有不慎,稳定的排序算法也能被写成不稳定的排序算法,比如下面的冒泡排序代码是不稳定的。
在这里插入图片描述
在这里插入图片描述

选择排序

执行流程:

  • ① 从序列中找出最大的那个元素,然后与最未尾的元素交换位置
    执行完一轮后,最未尾的那个元素就是最大的元素。
  • ② 忽略①中曾经找到的最大元素,重复执行步骤①。
    在这里插入图片描述
/**
 * 选择排序
 */
public class SelectionSort<T extends Comparable<T>> extends Sort<T> {

	@Override
	protected void sort() {
		for (int end = array.length - 1; end > 0; end--) {
			int max = 0;
			for (int begin = 1; begin <= end; begin++) {
				if (cmp(max, begin) < 0) {
					max = begin;
				}
			}
			swap(max, end);
		}
	}
}

在这里插入图片描述

选择排序的交换次数要远远少于冒泡排序,平均性能优于冒泡排序。

复杂度与稳定性

在这里插入图片描述

堆排序

执行流程:

  1. 对序列进行原地建堆(heapify)O(N)
  2. 重复执行以下操作(依次取出堆中最大值,并删除),直到堆的元素数量为 1 ,N-I次 O(N)
    • 交换堆顶元素与堆尾元素(把最大值放到最后面)O(1)
    • 堆的元素数量减 1(不管最后已经放到最后的最大值)O(1)
    • 对 0 位置进行 1 次 siftDown (建堆)操作O(log(N))

时间复杂度:O(N+Nlog(N)) --> O(NlogN)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值