冒泡法排序优化: 在一趟冒泡中如果没有交换记录,那么可结束排序
选择法排序优化: 在每一趟选择时不必交换记录值,只需记录下最小元素的序号即可
位图算法:
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进行统计个数。那该如何处理呢?请大家看下面的方法,我们首先通过例子来说明:
2 | 1 | 1 | 3 | 3 | 2 |
p1 | p2 | p3 |
假设,我们有三个指针:p1、p2、p3.p1从左侧开始,指向第一个非1的数字;p3从右侧开始,指向第一个非3的数字。p2从p1开始遍历,如果是2,p2继续遍历,直到p2遇到1或者3:
-
如果遇到1,则和p1进行交换,然后p1向右,指向第一个非1的数字
-
如果遇到3,则和p3进行交换,然后p3向左,指向第一个非3的数字
1 | 2 | 1 | 3 | 3 | 2 |
p1,p2 | p3 |
交换之后,p2继续从p1开始(注意这步只是按上图情形下的说法,而不是通用操作,p2继续从原来的位置向右才对),如果是2继续遍历,如果是1或者3,重复上面的步骤,所得如下:
1 | 1 | 2 | 3 | 3 | 2 |
p1,p2 | p3 |
根据上面的方法继续下去
1 | 1 | 2 | 2 | 3 | 3 |
p1 | p3 | p2 |
p2在p3右侧,算法结束。
总结一下上面的算法:
p1从左侧开始,指向第一个非1的数字;p3从右侧开始,指向第一个非3的数字。
-
p2从p1开始遍历,如果是2,p2继续遍历,直到p2遇到1或者3
-
如果遇到1,则和p1进行交换,然后p1向右,指向第一个非1的数字
-
如果遇到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