数据结构与算法---排序---选择排序、堆排序

选择排序(Selection Sort)

选择排序大致就是,每次循环找出最大值,然后与最后一个元素进行交换。然后再在除最后一个元素的数组里面,再找出最大值,与倒数第二个元素进行交换,以此类推。

执行流程:

1 从序列中找出最大的那个元素,然后与最末尾的元素交换位置。
执行完一轮后,最末尾的那个元素就是最大的元素

2 忽略1中曾经找到的最大元素,重复执行步骤1

不难写出代码:

public class test {

	public static void main(String[] args) {
		
		int[] array = {1, 3, 4, 19, 8 ,6};
		
		for (int end = array.length - 1; end > 1; end--) {
			int maxIndex = 0;
			for (int begin = 1; begin <= end; begin++) {
				
				//假如数组是:3 3 1
				//如果是<号,array[0] = array[1],将第一个3放在了最后,显然不是稳定的。
				//因此,此处需要是<=
				if (array[maxIndex] <= array[begin]) {
					maxIndex = begin;
				}
			}
			//交换
			int temp = array[maxIndex];
			array[maxIndex] = array[end];
			array[end] = temp;
		}
		
		for (int i = 0; i < array.length; i++) {
			System.out.print(array[i] + " ");
		}
	}

}

虽然array[maxIndex] <= array[begin]一定程度上保证了选择排序的稳定性,但选择排序终究还是不稳定排序
例如:
10, 2a, 4, 2b
2b, 2a, 4, 10
不稳定了
因此,array[maxIndex] <= array[begin]写<=或者<都可以。

选择排序复杂度分析

选择排序的最好、最坏、平均时间复杂度为O(n2)
空间复杂度为O(1)
属于不稳定排序

与冒泡排序比较

选择排序与冒泡排序相比,比较次数要少很多。
冒泡排序需要每一次循环都要两两比较,如果前大后小,则交换。
选择排序只需要每一次循环找出最大值,最大值与最后值相交换即可。

如何优化?

从代码可以看出,选择排序每次都要选出最大元素。那么,我们是否可以使用大顶堆,因为对于大顶堆,最上面的元素就是最大值。而且,每次取最大值的平均时间复杂度为O(logn),比现在的选择最大值的时间复杂度O(n)要小。

这就是堆排序


堆排序(Heap Sort)

堆排序可以认为是对选择排序的一种优化

优化在于,每次取最大值的时候,是使用堆来取。

执行流程:

1 对序列进行原地建堆(heapify)
2 重复执行以下操作,直到堆的元素数量为1

  • 交换堆顶元素与尾元素
  • 堆的元素数量减1
  • 堆0位置进行1次siftDown操作

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

堆排序的最好、最坏、平均时间复杂度为O(nlogn),空间复杂度为O(1),属于不稳的排序。

在这里插入图片描述

可以看出,堆排序的所用时间比冒泡少了很多,也优于选择排序。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值