算法相关学习

冒泡法排序优化: 在一趟冒泡中如果没有交换记录,那么可结束排序

选择法排序优化: 在每一趟选择时不必交换记录值,只需记录下最小元素的序号即可

 

位图算法:

java.util.BitSet可以按位存储。
计算机中一个字节(byte)占8位(bit),我们java中数据至少按字节存储的,
比如一个int占4个字节。
如果遇到大的数据量,这样必然会需要很大存储空间和内存。
如何减少数据占用存储空间和内存可以用算法解决。
java.util.BitSet就提供了这样的算法。
比如有一堆数字,需要存储,source=[3,5,6,9]
用int就需要4*4个字节。
java.util.BitSet可以存true/false。
如果用java.util.BitSet,则会少很多,其原理是:
1,先找出数据中最大值maxvalue=9
2,声明一个BitSet bs,它的size是maxvalue+1=10
3,遍历数据source,bs[source[i]]设置成true.
最后的值是:
(0为false;1为true)
bs [0,0,0,1,0,1,1,0,0,1]
                3,   5,6,       9

这样一个本来要int型需要占4字节共32位的数字现在只用了1位!
比例32:1  
这样就省下了很大空间

 

分析:

位图算法其实是以key为整数,以boolean为value,作为简化版的Map,来对不重复的整数集进行排序的方法;当然也可以判断一个整数集中哪些数是重复的.相对于Map来说,BitSet的方式处理大数据较节省空间,提高运行效率,但是也有缺点,就是只能处理整数集,并且不能对含有重复值的整数集进行排序

 

指针法排序:

排序只有1,2,3三个元素的数组,不能统计1,2,3的个数

分析

这个题目,尽管也是排序,但却不能使用快速排序的方法。只有三个元素,如果时间复杂度仍旧是O(nlogn),显然不是最好的。那就可以使用线性的排序算法,例如计数排序,可是题目中要求,不能够对1,2,3进行统计个数。那该如何处理呢?请大家看下面的方法,我们首先通过例子来说明:

211332
p1p2   p3

假设,我们有三个指针:p1、p2、p3.p1从左侧开始,指向第一个非1的数字;p3从右侧开始,指向第一个非3的数字。p2从p1开始遍历,如果是2,p2继续遍历,直到p2遇到1或者3:

  1. 如果遇到1,则和p1进行交换,然后p1向右,指向第一个非1的数字

  2. 如果遇到3,则和p3进行交换,然后p3向左,指向第一个非3的数字

121332
 p1,p2   p3

交换之后,p2继续从p1开始(注意这步只是按上图情形下的说法,而不是通用操作,p2继续从原来的位置向右才对),如果是2继续遍历,如果是1或者3,重复上面的步骤,所得如下:

112332
  p1,p2  p3

根据上面的方法继续下去

112233
  p1p3p2 

p2在p3右侧,算法结束。

总结一下上面的算法:

p1从左侧开始,指向第一个非1的数字;p3从右侧开始,指向第一个非3的数字。

  1. p2从p1开始遍历,如果是2,p2继续遍历,直到p2遇到1或者3

  2. 如果遇到1,则和p1进行交换,然后p1向右,指向第一个非1的数字

  3. 如果遇到3,则和p3进行交换,然后p3向左,指向第一个非3的数字

 

重复上面的步骤,直到p2在p3的右侧结束。

 

分析: 指针法排序只能对含有三类值的数组进行排序

 

判断单向链表是否有环的快慢指针算法原理:

http://www.cnblogs.com/zhyg6516/archive/2011/03/29/1998831.html

 

快速排序算法:

 

public static void orderByFast(int[] a, int low, int high) {

		if (low < high) {
			int p = partition(a, low, high);
			orderByFast(a, low, p - 1);
			orderByFast(a, p + 1, high);

		}
	}
	
	static int i = 0;
	public static int partition(int [] a, int low, int high){
		int pivotkey = a[low];	//可以取 a[low],a[high],a[(low+high)/2]的中值,效率比较高
		while(low < high){
			while(low < high && a[high] >= pivotkey){
				high--;
			}
			a[low] = a[high]; //其实是用a[high]取代pivotkey所在位: a[(low+high)/2] = a[high]
			System.out.println("第  " + (++i) + " 次移动");
			while(low < high && a[low] <= pivotkey){
				low++;
			}
			a[high] = a[low]; //其实是用a[low]取代pivotkey所在位: a[(low+high)/2] = a[low]
			System.out.println("第  " + (++i) + " 次移动");
		}
		a[low] = pivotkey; ///
		System.out.println("第  " + (++i) + " 次移动");
		return low;
		
	}

 

 

详解11种排序算法 http://blog.csdn.net/speedme/article/details/23021467 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值