Java编程实现数组排序——(三)选择排序

选择排序的基本思想:每一趟在n-i+1(i=1,2,3...,n-1)个记录中选取关键字最小的记录作为有序序列的第i个记录

一、简单选择排序

一趟简单选择排序:通过n-i次关键字之间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1 ≦ i ≦ n)个记录交换。

令 i 从 1 至 n-1 进行 n-1 趟选择操作,其时间复杂度为O(n^2) 。

排序代码如下:

public class Demo03 {
	/*
	 * 一趟简单选择排序,返回其中最小值的下标
	 */
	private static int selectMinKey(int[] arr,int i){
		int temp=i;
		for(int k=i;k<arr.length;k++){
			if(arr[temp]>arr[k])
				temp=k;
		}
		return temp;
	}
	/*
	 * 选择排序,若最小值不是当前元素,进行交换
	 */
	public static void selectSort(int[] arr){
		for(int i=0;i<arr.length;i++){
			int j=selectMinKey(arr, i);
			if(i!=j){
				int t=arr[i];
				arr[i]=arr[j];
				arr[j]=t;
			}
		}
	}
	public static void main(String[] args) {
		int[] arr=new int[10];
		arr[0]=0;
		arr[1]=15;
		arr[2]=98;
		arr[3]=105;
		arr[4]=45;
		arr[5]=8;
		arr[6]=51;
		arr[7]=18;
		arr[8]=66;
		arr[9]=21;
		selectSort(arr);
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+" ");
		}
	}
}

二、树形选择排序

由上面我们可以知道,选择排序关键字之间要进行n(n-1)/2次的比较,减少比较次数是改进简单选择排序算法的思路之一。

树形选择排序又称为锦标赛排序,它首先对n个记录的关键字进行两两比较,然后在其中n/2个较小者当中再进行两两比较,反复进行,直到选出最小的关键字为止。

树形选择排序存在着需要辅助存储空间较多以及多余比较的缺点,其时间复杂度为O(nlogn) 。

三、堆排序

若将堆对应的一维数组看成是一棵完全二叉树,则其含义可以阐述为:完全二叉树中所有非终端结点的值均不大于(或不小于)其左右孩子结点的值。

堆排序的定义为:

    若在输出堆顶的最小值之后,使得剩余的n-1个元素的序列又重构成一个堆,则得到 n 个元素中的次小值,如此反复执行,便能够得到一个有序序列。

堆排序的运行时间主要消耗在初始建堆和堆重构上,对于记录较少的文件并不值得提倡,但对于n较大的文件来说还是十分有效的。

堆排序的优点:

1)即使是在最坏情况下,其时间复杂度也是O(nlogn)。

2)只需要一个记录大小的供交换使用的辅助存储空间。

其Java实现代码如下:

/**
 * 堆排序
 * 堆采用顺序结构存储
 * @author Administrator
 *
 */
public class Demo09 {
	/**
	 * 在arr[s...m]中的关键字除了arr[s]外均满足堆的定义
	 * 本函数调整arr[s]关键字,使得arr[s...m]成为一个大顶堆。
	 * @param arr
	 * @param s
	 * @param m
	 */
	private static void heapAdjust(int[] arr,int s,int m){
		int rc=arr[s];
		/*
		 * 沿着关键字较大的孩子结点向下筛选
		 */
		for(int j=2*s;j<=m;j*=2){
			//j为关键字较大的记录的下标
			if(j<m&&arr[j]<arr[j+1])
				j++;
			if(!(rc<arr[j]))
				break;
			arr[s]=arr[j];
			s=j;
		}
		arr[s]=rc;
	}
	/**
	 * 对顺序表进行堆排序
	 * @param arr
	 */
	public static void heapSort(int[] arr){
		/*
		 * 把arr[1...arr.length-1]建成大顶堆
		 */
		for(int i=arr.length/2;i>0;i--)
			heapAdjust(arr, i, arr.length-1);
		for(int i=arr.length-1;i>1;i--){
			int temp=arr[1];
			arr[1]=arr[i];
			arr[i]=temp;
			heapAdjust(arr, 1, i-1);
		}
	}
	public static void main(String[] args) {
		int[] arr=new int[10];
		arr[0]=0;
		arr[1]=15;
		arr[2]=98;
		arr[3]=105;
		arr[4]=45;
		arr[5]=8;
		arr[6]=51;
		arr[7]=18;
		arr[8]=66;
		arr[9]=21;
		heapSort(arr);
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+" ");
		}
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值