Chinaunix首页 | 论坛 | 博客
  • 博客访问: 506206
  • 博文数量: 184
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1172
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-21 13:40
个人简介

技术改变命运

文章分类

全部博文(184)

文章存档

2020年(16)

2017年(12)

2016年(156)

我的朋友

分类: C/C++

2016-07-07 18:31:14

重要结论:对于2n = 3^k-1长度的数组,恰好只有n个圈,且每个圈头部的起始位置分别是1,3,9,...,3^(k-1).
c代码如下:
数组为{a1,a2,...,a7,b1,b2...b7}

k

m

n2

n2/m

>3

0

1

14

14

y

1

3

14

4

y

2

9

14

0

n

时间复杂度是O(n),空间复杂度是O(1)

点击(此处)折叠或打开

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define N 9
  4. #define swap(t,x,y) (t = (x),x = (y),y = (t))
  5. int b[N];
  6. void CycleLeader(int *a,int from,int mod)//一次走环算法
  7. {
  8.     int t,i;
  9.     for (i = from*2 % mod;i != from;i = i*2 % mod)
  10.     {
  11.         t = a[i];
  12.         a[i] = a[from];
  13.         a[from] = t;
  14.     }
  15.     
  16.     
  17. }
  18. /*思想:把前n-m个元素(m+1,...,n)和后m个元素(m+1,...n+m)先各自反转,在将整个段反转
  19. void reverse(int *a,int from,int to)//循环位移算法
  20. {
  21.     int t;
  22.     for (;from < to;++from,--to)
  23.     {
  24.         t = a[from];
  25.         a[from] = a[to];
  26.         a[to] = t;
  27.     }
  28. }
  29. void RightRotate(int *a,int num,int n)
  30. {
  31.     reverse(a,1,n-num);
  32.     reverse(a,n-num+1,n);
  33.     reverse(a,1,n);
  34. }
  35. void PerfectShuffle(int *a,int n)
  36. {
  37.     int n2,m,i,k,t;
  38.     if (n >1)
  39.     {
  40.         n2 = n*2;
  41.         //找到 2m = 3^k-1,使得3^k <= 2n < 3^(k+1)
  42.         for (k = 0,m = 1;n2 / m >= 3;++k,m *= 3)
  43.             ;
  44.         m /= 2;
  45. //2m = 3 ^k-1,3 ^k <= 2n < 3^(k+1)
  46.         //把数组中A[m+1,...n+m]那部分循环右移m位

  47.         RightRotate(a+m,m,n);
  48. //对于2m长度的数组,刚好有k个圈,且每个圈的头部为3^i,对每个圈执行CycleLeader算法
  49.         for (i = 0,t = 1;i < k;++i,t *= 3)
  50.         {
  51.             CycleLeader(a,t,m*2+1);
  52.         }
  53.         PerfectShuffle(a+2*m,n-m);
  54.     }
  55.     if (n == 1)
  56.     {
  57.         t = a[1];
  58.         a[1] = a[2];
  59.         a[2] = t;
  60.     }
  61. }
  62. void Shuffle(int *a,int n)
  63. {
  64.     int i,t,n2 = n*2;
  65.     PerfectShuffle(a,n);
  66.     for (i = 2;i <= n2;i += 2)//相邻元素交换算法
  67.     {
  68.         t = a[i-1];
  69.         a[i-1] = a[i];
  70.         a[i] = t;    
  71.     }
  72. }

  73. int main()
  74. {
  75.     int a[9] = {0,1,2,3,4,5,6,7,8};
  76.     Shuffle(a,4);
  77.     int i = 0;
  78.     for (i = 1;i <=8;i++)
  79.     {
  80.         printf("%d ",a[i]);
  81.     }
  82.     printf("\n");
  83.     return 0;
  84. }
阅读(693) | 评论(0) | 转发(0) |
0

上一篇:完美洗牌算法(1)

下一篇:约瑟夫斯问题

给主人留下些什么吧!~~