排序算法小结(三)——选择类排序(Java实现):简单选择排序、树形选择排序、堆排序

目录

1.简单选择排序

2.树形选择排序

3.堆排序

4.总结


1.简单选择排序

简单选择排序的基本思想非常简单,即:第一趟,从 n 个元素中找出关键字最小的元素与第一个元素交换;第二趟,在从第二个元素开始的 n-1 个元素中再选出关键字最小的元素与第二个元素交换;如此,第 k 趟,则从第 k 个元素开始的 n-k+1 个元素中选出关键字最小的元素与第 k 个元素交换,直到整个序列按关键字有序。

Java实现代码如下:

	public static void simpleSelectSort(int arr[]) {
		int min;
		for(int i=0;i<arr.length-1;i++) {
			min = i;
			for(int j=i+1;j<arr.length;j++)
				if(arr[j]<arr[min])
					min=j;
			if(min!=i) {
				arr[min] = arr[min]+arr[i];
				arr[i] = arr[min]-arr[i];
				arr[min] = arr[min]-arr[i];
			}
		}
	}

2.树形选择排序

3.堆排序

关于什么是大/小顶堆,自行查阅资料。堆排序的思路为:设有 n 个元素,欲将其按关键字排序。可以首先将这 n 个元素按关键字建成堆,将堆顶元素输出,得到 n 个元素中关键字最大(或最小)的元素。然后,再将剩下的 n-1 个元素重新建成堆,再输出堆顶元素,得到 n 个元素中关键字次大(或次小)的元素。如此反复执行, 直到最后只剩一个元素,则可以得到一个有序序列,这个排序过程称之为堆排序。

从对排序的过程中可以看到,在实现对排序时需要解决两个问题:

1.如何将 n 个元素的序列按关键字建成堆;

2.输出堆顶元素后,怎样调整剩余 n-1 个元素,使其按关键字成为一个新堆。

我们首先第二个问题,即输出堆顶元素后,对剩余元素重新建成堆的调整过程。

设有一个具有 m 个元素的堆,输出堆顶元素后,剩下 m-1 个元素。具体的调整方法是: 首先,将堆底元素(最后一个元素)送入堆顶,此时堆被破坏,其原因仅是根结点不满足堆的性质,而根结点的左右子树仍是堆。然后,将根结点与左、右子女中较大(或较小)的进行交换。若与左孩子交换,则左子树堆被破坏,且仅左子树的根结点不满足堆的性质;若与右孩子交换,则右子树堆被破坏,且仅右子树的根结点不满足堆的性质。继续对不满足堆性质的子树进行上述交换操作,直到叶子结点,则堆被重建。我们称这个自根结点到叶子结点的调整过程为筛选。

由此,如果我们能够建立一个堆,那么排序的过程就是不断输出堆顶并进行筛选的过程。现在的关键问题是如何由一个元素的初始序列构造一个堆,实际上建堆的方法是逐层向上对每个非终端结点进行一次筛选即可。

初始建堆首的过程,以按层从下到上的第一个非叶子结点开始。对于数组int arr[],将元素构成一颗完全二叉树,arr[i]的左子节点为arr[2i+1],右子节点为arr[2i+2];父节点为(i-1)/2。

堆调整的过程Java代码如下:

    /**
	 * arr[low]为根节点,除了根节点外其余节点均满足大顶堆
	 * @param arr
	 * @param low
	 * @param high
	 */
	public static void heapAjust(int arr[],int low,int high) {
		int min = arr[low];
		for(int i=2*low+1;i<=high;i=2*i+1) {
			if(i<high&&arr[i]<arr[i+1]) i++;
			if(min>=arr[i]) break;
			arr[low] = arr[i];
			low = i;
		}
		arr[low] = min;
	}

初始序列建堆及排序Java实现如下:

	public static void heapSort(int arr[]) {
		for(int i = (arr.length-2)/2;i>=0;i--)//建堆
			heapAjust(arr, i, arr.length-1);
		for(int i = arr.length-1;i>0;i--) {//筛选
			arr[i]=arr[i]+arr[0];
			arr[0]=arr[i]-arr[0];
			arr[i]=arr[i]-arr[0];
			heapAjust(arr, 0, i-1);
		}
	}

4.总结

简单选择排序的时间复杂度为O(n2),是一种不稳定的排序算法;堆排序的时间复杂度为Ο(n log n), 是一种不稳定的排序算法。选取10万个随机整数排序耗时测试如图:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值