1. package lhz.algorithm.chapter.five;
  2. /**
  3. * 随机数组两种实现,《算法导论》第五章第三节
  4. * 本文地址:http://mushiqianmeng.blog.51cto.com/3970029/734384
  5. * @author lihzh(苦逼coder)
  6. */
  7. public class RandomArray {
  8. private static int[] arrayOne = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
  9. 11, 12, 13 };
  10. private static int[] arrayTwo = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
  11. 11, 12, 13 };
  12. public static void main(String[] args) {
  13. //随机方式一,排列数组一
  14. permuteBySorting(arrayOne);
  15. //打印数组一
  16. printArray(arrayOne);
  17. System.out.println("");
  18. //随机方式二,排列数组二
  19. randomizeInPlace(arrayTwo);
  20. //打印数组二
  21. printArray(arrayTwo);
  22. }
  23. /**
  24. * 随机化数组方式一,采用优先级数组比照方式
  25. * PERMUTE-BY-SORTING(A)
  26. * 1 n ← length[A]
  27. * 2 for i ← 1 to n
  28. * 3 do P[i] =RANDOM(1, n^3)
  29. * 4 sort A, using P as sort keys
  30. * 5 return A
  31. */
  32. private static void permuteBySorting(int[] input) {
  33. int n = input.length;
  34. int[] p = new int[n];
  35. for (int i = 0; i < n; i++) {
  36. p[i] = randomValue(n);
  37. }
  38. mergeSort(input, p);
  39. /*
  40. *复杂度分析:
  41. *因为采用了合并排序,所以可知复杂度为:Θ(n lg n)
  42. */
  43. }
  44. /**
  45. * 随机化数组方式二,直接位置交换方式
  46. * 复杂度为:O(n)
  47. * RANDOMIZE-IN-PLACE(A)
  48. *  1 n ← length[A]
  49. *  2 for i ← to n
  50. *  3 do swap A[i] ↔ A[RANDOM(i, n)]
  51. * @param input
  52. */
  53. private static void randomizeInPlace(int[] input) {
  54. int n = input.length;
  55. for (int i = 0; i < n; i++) {
  56. int index = (int) (Math.random() * (n - i - 1) + i);
  57. int temp = input[index];
  58. input[index] = input[i];
  59. input[i] = temp;
  60. }
  61. }
  62. /**
  63. * 产生从1到n^3的随机数
  64. * @param n
  65. * @return
  66. */
  67. private static int randomValue(int n) {
  68. return (int) (Math.random() * (n * n * n - 1) + 1);
  69. }
  70. /**
  71. * 改写的合并排序,根据数组P中定义的优先级决定顺序。
  72. * @param array
  73. * @return
  74. */
  75. private static int[] mergeSort(int[] array, int[] keyArray) {
  76. // 如果数组的长度大于1,继续分解数组
  77. if (array.length > 1) {
  78. int leftLength = array.length / 2;
  79. int rightLength = array.length - leftLength;
  80. // 创建两个新的数组
  81. int[] left = new int[leftLength];
  82. int[] right = new int[rightLength];
  83. // 创建两个新的key数组
  84. int[] leftKey = new int[leftLength];
  85. int[] rightKey = new int[rightLength];
  86. // 将array中的值分别对应复制到两个子数组中
  87. for (int i = 0; i < leftLength; i++) {
  88. left[i] = array[i];
  89. leftKey[i] = keyArray[i];
  90. }
  91. for (int i = 0; i < rightLength; i++) {
  92. right[i] = array[leftLength + i];
  93. rightKey[i] = keyArray[leftLength + i];
  94. }
  95. // 递归利用合并排序,排序子数组
  96. left = mergeSort(left,leftKey);
  97. right = mergeSort(right,rightKey);
  98. // 设置初始索引
  99. int i = 0;
  100. int j = 0;
  101. for (int k = 0; k < array.length; k++) {
  102. // 如果左边数据索引到达边界则取右边的值
  103. if (i == leftLength && j < rightLength) {
  104. array[k] = right[j];
  105. j++;
  106. // 如果右边数组索引到达边界,取左数组的值
  107. } else if (i < leftLength && j == rightLength) {
  108. array[k] = left[i];
  109. i++;
  110. // 如果均未到达边界,则根据优先级数组中定义的顺序排序
  111. } else if (i < leftLength && j < rightLength) {
  112. if (leftKey[i] > rightKey[j]) {
  113. array[k] = right[j];
  114. j++;
  115. } else if (leftKey[i] < rightKey[j]){
  116. array[k] = left[i];
  117. i++;
  118. }
  119. }
  120. }
  121. }
  122. return array;
  123. }
  124. private static void printArray(int[] array) {
  125. for (int i : array) {
  126. System.out.print(i + " ");
  127. }
  128. }
  129. }

转载于:https://blog.51cto.com/mushiqianmeng/734384

算法导论Java实现-随机化数组的两种方式(5.3章节)相关推荐

  1. Java中HashMap遍历的两种方式

    第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Ma ...

  2. java读取csv文件的两种方式

    java读取csv文件的两种方式 1.CsvReader读取 import com.csvreader.CsvReader; /*** CsvReader 读取* @param filePath* @ ...

  3. Java判断回文数(两种方式)

    Java判断回文数(两种方式) 回文数是一个非常特殊的数,它从左边读和从右边读是一样的.例如12321 判断方式有两种. 方式一:对该数字进行分解,然后一一比对,拆解成 1 2 3 2 1,然后第一位 ...

  4. Java中Http连接的两种方式

    在java中连接http,介绍两种方法,一种是java的HttpUrlConnection,另一种是apacha公司的httpClient,后者是第三方的类库需要从外部,导入,同时这也是第一次使用外部 ...

  5. 代码示例:Java中定义数组的三种方式

    在Java中,数组的定义有三种方式,其基本语法格式如下: 数组类型[] 数组名 = new 数组类型[数组长度]; 数组类型[] 数组名 = new 数组类型[]{数组元素0,数组元素1,...}; ...

  6. Java中实现多线程的两种方式之间的区别

    Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...

  7. java中实现同步的两种方式:syschronized和lock的区别和联系

    转载自 http://www.cnblogs.com/xiohao/p/4151408.html Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用s ...

  8. java jobdetail_Spring创建JobDetail的两种方式

    一.Spring创建JobDetail的两种方式 定时任务两种方式,Spring很好的封装使用Quartz的细节,第一种方式是利用SPring封装的Quartz类进行特定方法的实现,第二种是通过透明的 ...

  9. java中定义数组的3种方式

    直接上代码和截图 public static void main(String[] args) {// 定义数组的3种方式// 第一种String[] role = new String[3];rol ...

最新文章

  1. mvc学习-编辑提交需要注意-mvc重点
  2. 深度学习(八)RBM受限波尔兹曼机学习-未完待续
  3. Linux漏洞CVE整理
  4. [Xcode 实际操作]六、媒体与动画-(6)使用UIBlurEffect给图片添加模糊效果
  5. 分布式日志收集系统Apache Flume的设计详细介绍
  6. python dataframe索引_pandas DataFrame 行列索引及值的获取的方法
  7. XMPP的简介和基本概念
  8. 华为方舟编译器是黑科技?
  9. Java程序员校招蚂蚁金服,大专生出身,做Java程序员真的没有春天吗
  10. shell 获取指定ip的丢包率
  11. 基于51单片机的交通灯原理图加代码
  12. 台式计算机分享无线网,台式机如何去共享wifi
  13. Python-伪数据构造神库Faker
  14. 服务器怎么组装,如何组装一台服务器?(最好标明下什么类型的)
  15. 漫谈直播:从零开始认识直播并快速搭建专属直播平台
  16. python math库 sqrt eval_假设 math 标准库已导入,那么表达式 eval('math.sqrt(4)') 的值为 _________ 。( ) (2.0分)_学小易找答案...
  17. 【数论】同余(五):多元线性同余方程
  18. 算法学习过程入门篇(2)-算法初步
  19. case/casez/casex 的区分与使用
  20. STM32——快速识别芯片引脚数

热门文章

  1. 这个AI“大师级”简笔画水平,惊艳到了网友:竟然不用GAN
  2. Beta冲刺提交-星期四
  3. Hadoop搭建完全分布式
  4. 事务-07-微服务架构的设计模式
  5. ssh在dhcp自动获取地址的时候使用
  6. scala简单学习---1
  7. spring webflow
  8. Python LOGGING使用方法
  9. VS2010 出现打开关联文档错误的解决方案
  10. lesson4-Qt窗口