Java基础之排序算法

Posted 刘兆贤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础之排序算法相关的知识,希望对你有一定的参考价值。

                                                          本文来自刘兆贤的博客_CSDN博客-Java高级,Android旅行,Android基础领域博主 ,引用必须注明出处!

新年第一篇,总结下基础的算法,包含二分排序、快速排序和分治排序

1、分治(归并)排序,将数组分成一个个小数据块,每块小于3个元素,分别排序后再进行合并。

	private int[] fenzhi(int[] attr) 
		if (attr.length > 2) 
			int[] first = new int[attr.length / 2];
			System.arraycopy(attr, 0, first, 0, first.length);
			int[] last = new int[attr.length - attr.length / 2];
			System.arraycopy(attr, attr.length / 2, last, 0, last.length);
			return merge(fenzhi(first), fenzhi(last));
		
		attr = sort(attr);
		return attr;
	

	/**
	 * 只剩下1个或2个,或者0个元素
	 * 
	 * @param attr
	 * @return
	 */
	private int[] sort(int[] attr) 
		if (attr.length == 2) 
			if (attr[1] < attr[0]) 
				int tem = attr[1];
				attr[1] = attr[0];
				attr[0] = tem;
			
		
		return attr;
	

	private int[] merge(int[] attr1, int[] attr2) 
		int attr[] = new int[attr1.length + attr2.length];
		int count = 0;
		for (int i = 0, j = 0; i < attr1.length || j < attr2.length;) 
			if (i < attr1.length && j < attr2.length) 
				int av = attr1[i];
				int bv = attr2[j];
				if (av <= bv) 
					attr[count++] = av;
					i++;
				 else 
					attr[count++] = bv;
					j++;
				
			 else if (i < attr1.length) 
				attr[count++] = attr1[i];
				i++;
			 else if (j < attr2.length) 
				attr[count++] = attr2[j];
				j++;
			
		
		return attr;
	

思路还是比较清晰,只是空间复杂度高一些O(2^n),时间复杂度为nlog(n)--每次包含分治、排序、合并三个过程。

2、二分排序,实际上是二分查找+插入排序的结合体

	private int[] erfen(int attr[]) 
		for (int i = 1; i < attr.length; i++) 
			int tem;
			if (attr[i] < attr[i - 1]) 
				// 默认数组有序,查找出,第一个无序的元素
				tem = attr[i];
			 else 
				continue;
			
			int low = 0;
			int high = i - 1;
			while (low <= high) 
				// 等号,处理边界值,一直比当前值小,但比最小数大
				int mid = low + high >> 1;
				if (attr[mid] > tem) 
					high = mid - 1;
				 else 
					low = mid + 1;
				
			
			for (int j = i; j > low; j--) 
				// low位即tem的位置,需要将它和后续元素均后移
				attr[j] = attr[j - 1];
			
			attr[low] = tem;
		
		return attr;
	

时间复杂度为nlog(n),空间复杂度O(n^2)

3、快速排序,快排,时间复杂度,预期为nlog(n)---共logn个数组,每个数组遍历一次,共nlogn次。最差为O(n^2)--已经排好序,但选择从下标0开始,要遍历n次,计n个数据,即n^2。

	private int[] quick2(int[] attr, int left, int right) 
		if (left >= right) 
			// 说明已经找完
			return attr;
		
		int tar = attr[left];
		int low = left;
		int high = right;
		while (low < high) 
			while (low < high && attr[high] >= tar) 
				// 从右向左查询,直到小于tar或者越界则停止
				high--;
			
			// 高低位互换,让小数到前面去
			attr[low] = attr[high];
			while (low < high && attr[low] < tar) 
				// 从左向右查询,直到大于或越界则停止
				low++;
			
			// 低高位互换,让大数到后面去
			attr[high] = attr[low];
		
		// 互换后,tar左边都是小数,右边都是大数
		attr[low] = tar;
		// 左快排
		quick2(attr, left, low - 1);
		// 右快排
		quick2(attr, low + 1, right);
		return attr;
	

以上是关于Java基础之排序算法的主要内容,如果未能解决你的问题,请参考以下文章

Java基础之排序算法

排序算法——基数排序

java基础算法之插入排序

java基础算法之快速排序

java基础之几种常见的排序算法

基数排序(数字排序和英文字母排序)