完美洗牌算法

来源:互联网 发布:做网络兼职是真的吗 编辑:程序博客网 时间:2024/05/01 13:30

有个长度为2n的数组{a1,a2,a3,...,an,b1,b2,b3,...,bn},希望排序后{a1,b1,a2,b2,....,an,bn},请考虑有无时间复杂度o(n),空间复杂度0(1)的解法。

#include <iostream>using namespace std;//翻转字符串时间复杂度O(to - from)void reverse(int *a, int from, int to) {int t;for (; from < to; ++from, --to) {t = a[from];a[from] = a[to];a[to] = t;}}//循环右移num位 时间复杂度O(n)void RightRotate(int *a, int num, int n) {reverse(a, 1, n - num);reverse(a, n - num + 1, n);reverse(a, 1, n);}/*领悟版:时间O(n),空间O(1) * 原理: *逐一处理序列对: *将当前序列对凑在一起: *将未处理序列的头元素与当前处理的序列对次元素换位(实际上是换位算法变形) 例:(1234)(5678)各一叠 1 2 3 4 5 6 7 8  未处理序列对:4 第一次: 1 5 2 3 4 6 7 8未处理序列对:3 第二次: 1 5 2 6 3 4 7 8 ... * */void perfectShuffle(int* a, int n) {while (n > 0) {RightRotate(a + 1, 1, n);a += 2;n--;}}//时间复杂度O(n),空间复杂度O(1),数组下标从1开始,调用perfect_shuffle3void shuffle(int *a, int n) {int i, t, n2 = n * 2;PerfectShuffle2(a, n);for (i = 2; i <= n2; i += 2) {t = a[i - 1];a[i - 1] = a[i];a[i] = t;}}


0 0