排序算法

昨天重温了一下插入排序与快速排序。

1,插入排序:将一个序列分为有序部分和无序部分,进行N-1次循环,每次将无序部分中的一个数插入到有序部分的相应位置。之后整个序列就是有序的。

算法复杂度O(N^2), 稳定排序。由于比较简单,不做具体分析,代码如下:

package sort;

public class InsertSort {

	public static void insertSort(int []a) {
		int j;
		int n = a.length;
		for(int i=1;i<n;i++)
		{
			int t = a[i];
			for(j = i; j>0 && a[j-1]>a[j]; j--)
				a[j] = a[j-1];
			a[j] = t;
		}
	}
	public static void main(String[] args) {
		int []a = {2, 1, 3, 5, 8, 7};
		insertSort(a);
		for(int i=0;i<a.length;i++){
			System.out.print(a[i] + " ");
			if(i==a.length-1) System.out.println();
		}
	}

}


2,快速排序:选择一个基准数,经过一趟排序,使得基准数左边的数都比它小,右边的都比它大(针对升序排列)。然后再对左右两边的区间递归调用快排。基准数的选取,一般会选择区间的第一个元素,为了更加平均的效率,随机数是一个比较好的选择。

直接贴代码

public class QuickSort{
	public static int partition(int []a, int l, int u){
		int k = a[l];
		while(l<u){
			while( l<u && a[u]>=k) -- u;
			a[l] = a[u];
			while( l<u && a[l]<=k) ++ l;
			a[u] = a[l];
		}
		a[l] = k;
		return l;
	}
	public static void quickSort(int []a, int l, int u){
		if(l>=u) return;
		int p = partition(a, l, u);
		quickSort(a, l, p-1);
		quickSort(a, p+1, u);
	}
	public static void main(String []args){
		int []a = {2, 3, 4, 6, 9, 2, 8};
		quickSort(a, 0, a.length-1);
		for(int i=0;i<a.length;i++){
			System.out.print(a[i] + " ");
			if(i==a.length-1) System.out.println();
		}
	}
}

3,堆排序:堆分为大根堆(a[i]>=a[2*i] && a[i]>=a[2*i+1] ) 和小根堆(a[i]<=a[2*i] && a[i]<=a[2*i+1] )。由此,堆的根节点即为最大值或者最小值,当不断拿走根节点并且使得剩下的部分重新调整为堆,即可实现排序。堆排序分为两个过程:1,建堆,即将一个乱序队列构建为堆;2,调整,即去掉根节点(最大值或者最小值)后调整剩下的部分使其继续为堆。  对于一个节点的树,已经是堆。对于二层树,如果最大值不是根,则最大值与根交换,这样就调整为堆。对于多层树,我们只需要从最后一个非叶节点调整就可以建堆。

排序过程,建堆,交换第一个节点与最后一个节点,这样最后一个数就已经在正确位置上,去掉已经在正确位置上的节点,调整。 依次下去就可排序。

注意, 如果需要升序排列,需要建立大根堆, 降序需要小根堆。

下面给出了递归和非递归的实现

public class HeapSort {

	public static void makeHeap(int []a, int len) {
		for(int i=len/2;i>=1;i--)
//			ajustHeap(a, i, len);
			ajustHeapNoRecursive(a, i, len);
	}
	public static void ajustHeap(int []a, int i, int len) {
		if( i > len/2 ) return; // 叶节点,不做处理
		int max = i;
		int lChild = i * 2;
		int rChild = i * 2 + 1;

		if(lChild<=len && a[lChild]>a[max]) max = lChild;
		if(rChild<=len && a[rChild]>a[max]) max = rChild;
		if(max != i) { // 需要调整顺序
			int tem = a[max];
			a[max] = a[i];
			a[i] = tem;
			ajustHeap(a, max, len);
		}
	}
	public static void ajustHeapNoRecursive(int []a, int i, int len) {
		while(i<=len/2) {
			int lChild = i * 2;
			int rChild = i * 2 + 1;
			int max = i;
		
			if(lChild<=len && a[lChild]>a[max]) max = lChild;
			if(rChild<=len && a[rChild]>a[max]) max = rChild;
			if(max != i) { // 需要调整顺序
				int tem = a[max];
				a[max] = a[i];
				a[i] = tem;
				i = max;
			}
			else return;
		}
	}
	
	public static void heapSort(int []a) {
		int len = a.length - 1;
		makeHeap(a, len);
		for(int i=len;i>1;i--){
			int tem = a[i];
			a[i] = a[1];
			a[1] = tem;
//			ajustHeap(a, 1, i-1);
			ajustHeapNoRecursive(a, 1, i-1);
		}
	}
	public static void main(String[] args) {
		int []a = {0, 4, 3, 5, 2, 6, 1, 9, 1};//第一个数字为无效数字,数组从1开始
		heapSort(a);
		for(int i=1;i<a.length;i++) System.out.print(a[i] + " ");
		System.out.println();
	}

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值