一些STL 算法实现
2014-04-21 01:39 crazyxiazi 阅读(227) 评论(0) 收藏 举报1.随机洗牌
保证每一个牌随机到任意位置的概率为1/n
for int i = n do swap(A[i],A[random(i,n)]);
一共的排列有n!种,如何证明其概率是 n!呢,有一种方式是这样的
第一次的概率是n第二次是n-1第三次是n-2故概率是n!。这个比较好理解,但是感觉不太能证明的感觉。
有一个证明如下,但是不太好理解:http://blog.csdn.net/cyningsun/article/details/7545679
第二种算法是符合要求的随机洗牌算法。
使用数学归纳法证明:
1、当n=1时,所以元素arr[0]在任何一个位置的概率为1/1,命题成立。
2、假设当n=k时,命题成立,即原数组中任何一个元素在任何一个位置的概率为1/k。
3、则当n=k+1时,当算法执行完k次时,前k个元素在前k个位置的概率均为1/k。当执行最后一步时,前k个元素中任何一个元素被替换到第k+1位置的概率为:(1-1/(k+1)) * 1/k = 1/(k+1); 在前面k个位置任何一个位置的概率为(1-1/(k+1)) * 1/k = 1/(k+1);故前k个元素在任意位置的的概率都为1/(k+1)所以,对于前k个元素,它们在k+1的位置上概率为1/(k+1)。对于第k+1个元素,其在原位置的概率为1/k+1,在前k个位置任何一个位置的概率为:(1-k/(k+1)) * (1/k)=1/(k+1),所以对于第k+1个元素,其在整个数组前k+1个位置上的概率也均为1/k+1。
综上所述,对于任意n,只要按照方案中的方法,即可满足每个元素在任何一个位置出现的概率均为1/n。
2.快速排序:
STL的sort算法的优化策略:
1、 数据量大时采用QuickSort,分段递归排序。
2、 一旦分段后的数据量小于某个门槛,为避免Quick Sort的递归调用带来的额外负荷,就改用Insertion Sort。
3、 如果层次过深,还会改用HeapSort
4、 “三点中值”获取好的分割 采用的是从首、中点、尾三个元素中取中值来得到这个标志元素
3.堆排序:
建堆的过程
1.有从底向上 :
- for(int i = (heapSize-1)/2; i >= 0; i--)
- {
- heapShiftDown(heap, i, heapSize ); //判断其i节点和i节点的左右节点是否有大小差别,若不是最大的则需要往下shift
- }
2.从顶向下
- for(int i = 1; i < heapSize; i++)
- {
- heapShiftUp(heap, i);
- }
4. 链表旋转:即ABCDEFG =》EFGABCD
1.双向旋转 DCBA GFE = 》EFGABCD
2.单向旋转:
浙公网安备 33010602011771号