原文地址:http://blog.csdn.net/qq446282412/article/details/8913690
2013-05-11 10:27
 
看到网上的一段关于对数组操作的代码,觉得有用,在此备用。

  1. <pre name="code" class="java">import java.util.ArrayList;
  2. import java.util.Arrays;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.Random;
  6. import java.util.TreeMap;
  7. /**
  8. * @desc 数组操作工具
  9. * @author OuyangPeng
  10. * @datatime 2013-5-11 10:31:02
  11. *
  12. */
  13. public class MyArrayUtils {
  14. /**
  15. * 排序算法的分类如下: 1.插入排序(直接插入排序、折半插入排序、希尔排序); 2.交换排序(冒泡泡排序、快速排序);
  16. * 3.选择排序(直接选择排序、堆排序); 4.归并排序; 5.基数排序。
  17. *
  18. * 关于排序方法的选择: (1)若n较小(如n≤50),可采用直接插入或直接选择排序。
  19. * (2)若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜;
  20. * (3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。
  21. *
  22. */
  23. /**
  24. * 交换数组中两元素
  25. *
  26. * @since 1.1
  27. * @param ints
  28. *            需要进行交换操作的数组
  29. * @param x
  30. *            数组中的位置1
  31. * @param y
  32. *            数组中的位置2
  33. * @return 交换后的数组
  34. */
  35. public static int[] swap(int[] ints, int x, int y) {
  36. int temp = ints[x];
  37. ints[x] = ints[y];
  38. ints[y] = temp;
  39. return ints;
  40. }
  41. /**
  42. * 冒泡排序方法:相邻两元素进行比较 性能:比较次数O(n^2),n^2/2;交换次数O(n^2),n^2/4<br>
  43. * 冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,<br>
  44. * 如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,<br>
  45. * 也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。<br>
  46.   冒泡排序算法的运作如下:<br>
  47. 1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。<br>
  48. 2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。<br>
  49. 3. 针对所有的元素重复以上的步骤,除了最后一个。<br>
  50. 4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。<br>
  51. * @since 1.1
  52. * @param source
  53. *            需要进行排序操作的数组
  54. * @return 排序后的数组
  55. */
  56. public static int[] bubbleSort(int[] source) {
  57. /*for (int i = 0; i < source.length - 1; i++) { // 最多做n-1趟排序
  58. for (int j = 0; j < source.length - i - 1; j++) { // 对当前无序区间score[0......length-i-1]进行排序(j的范围很关键,这个范围是在逐步缩小的)
  59. if (source[j] > source[j + 1]) { // 把大的值交换到后面
  60. swap(source, j, j + 1);
  61. }
  62. }
  63. }*/
  64. for (int i = source.length - 1; i>0 ; i--) {
  65. for (int j = 0; j < i; j++) {
  66. if (source[j] > source[j + 1]) {
  67. swap(source, j, j + 1);
  68. }
  69. }
  70. }
  71. return source;
  72. }
  73. /**
  74. * 选择排序法 方法:选择排序(Selection sort)是一种简单直观的排序算法,其平均时间复杂度为O(n2)。
  75. *      它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,
  76. *      再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此类推,直到所有元素均排序完毕。
  77. * 性能:选择排序的交换操作介于0和(n-1)次之间, 选择排序的比较操作为n(n-1)/2次之间,
  78. *       选择排序的赋值操作介于0和3(n-1)次之间,其平均时间复杂度为O(n2)
  79. * 交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CUP时间多,所以选择排序比冒泡排序快。
  80. * 但是N比较大时,比较所需的CPU时间占主要地位,所以这时的性能和冒泡排序差不太多,但毫无疑问肯定要快些。
  81. *
  82. * @since 1.1
  83. * @param source
  84. *            需要进行排序操作的数组
  85. * @return 排序后的数组
  86. */
  87. public static int[] selectSort(int[] source) {
  88. for (int i = 0; i < source.length; i++) {
  89. for (int j = i + 1; j < source.length; j++) {
  90. if (source[i] > source[j]) {
  91. swap(source, i, j);
  92. }
  93. }
  94. }
  95. return source;
  96. }
  97. /**
  98. * 插入排序 方法:将一个记录插入到已排好序的有序表(有可能是空表)中,从而得到一个新的记录数增1的有序表。 性能:比较次数O(n^2),n^2/4
  99. * 复制次数O(n),n^2/4 比较次数是前两者的一般,而复制所需的CPU时间较交换少,所以性能上比冒泡排序提高一倍多,而比选择排序也要快。
  100. *
  101. * @since 1.1
  102. * @param source
  103. *            需要进行排序操作的数组
  104. * @return 排序后的数组
  105. */
  106. public static int[] insertSort(int[] source) {
  107. for (int i = 1; i < source.length; i++) {
  108. for (int j = i; (j > 0) && (source[j] < source[j - 1]); j--) {
  109. swap(source, j, j - 1);
  110. }
  111. }
  112. return source;
  113. }
  114. /**
  115. * 快速排序 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。 步骤为:
  116. * 1. 从数列中挑出一个元素,称为 "基准"(pivot), 2.
  117. * 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面
  118. * (相同的数可以到任一边)。在这个分割之后,该基准是它的最后位置。这个称为分割(partition)操作。 3.
  119. * 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
  120. * 递回的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了
  121. * 。虽然一直递回下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
  122. *
  123. * @since 1.1
  124. * @param source
  125. *            需要进行排序操作的数组
  126. * @return 排序后的数组
  127. */
  128. public static int[] quickSort(int[] source) {
  129. return qsort(source, 0, source.length - 1);
  130. }
  131. /**
  132. * 快速排序的具体实现,排正序
  133. *
  134. * @since 1.1
  135. * @param source
  136. *            需要进行排序操作的数组
  137. * @param low
  138. *            开始低位
  139. * @param high
  140. *            结束高位
  141. * @return 排序后的数组
  142. */
  143. private static int[] qsort(int source[], int low, int high) {
  144. int i, j, x;
  145. if (low < high) {
  146. i = low;
  147. j = high;
  148. x = source[i];
  149. while (i < j) {
  150. while (i < j && source[j] > x) {
  151. j--;
  152. }
  153. if (i < j) {
  154. source[i] = source[j];
  155. i++;
  156. }
  157. while (i < j && source[i] < x) {
  158. i++;
  159. }
  160. if (i < j) {
  161. source[j] = source[i];
  162. j--;
  163. }
  164. }
  165. source[i] = x;
  166. qsort(source, low, i - 1);
  167. qsort(source, i + 1, high);
  168. }
  169. return source;
  170. }
  171. // /////////////////////////////////////////////
  172. // 排序算法结束
  173. // ////////////////////////////////////////////
  174. /**
  175. * 二分法查找 查找线性表必须是有序列表
  176. *
  177. * @since 1.1
  178. * @param source
  179. *            需要进行查找操作的数组
  180. * @return 需要查找的值在数组中的位置,若未查到则返回-1
  181. */
  182. public static int[] binarySearch(int[] source) {
  183. int i,j;
  184. int low, high, mid;
  185. int temp;
  186. for (i = 0; i < source.length; i++) {
  187. temp=source[i];
  188. low=0;
  189. high=i-1;
  190. while (low <= high) {
  191. mid = (low + high)/2;
  192. if (source[mid]>temp) {
  193. high=mid-1;
  194. } else {
  195. low = mid + 1;
  196. }
  197. }
  198. for (j= i-1; j>high;j--)
  199. source[j+1]=source[j];
  200. source[high+1]=temp;
  201. }
  202. return source;
  203. }
  204. /**
  205. * 反转数组
  206. *
  207. * @since 1.1
  208. * @param source
  209. *            需要进行反转操作的数组
  210. * @return 反转后的数组
  211. */
  212. public static int[] reverse(int[] source) {
  213. int length = source.length;
  214. int temp = 0;
  215. for (int i = 0; i < length >> 1; i++) {
  216. temp = source[i];
  217. source[i] = source[length - 1 - i];
  218. source[length - 1 - i] = temp;
  219. }
  220. return source;
  221. }
  222. /**
  223. * 在当前位置插入一个元素,数组中原有元素向后移动; 如果插入位置超出原数组,则抛IllegalArgumentException异常
  224. *
  225. * @param array
  226. * @param index
  227. * @param insertNumber
  228. * @return
  229. */
  230. public static int[] insert(int[] array, int index, int insertNumber) {
  231. if (array == null || array.length == 0) {
  232. throw new IllegalArgumentException();
  233. }
  234. if (index - 1 > array.length || index <= 0) {
  235. throw new IllegalArgumentException();
  236. }
  237. int[] dest = new int[array.length + 1];
  238. System.arraycopy(array, 0, dest, 0, index - 1);
  239. dest[index - 1] = insertNumber;
  240. System.arraycopy(array, index - 1, dest, index, dest.length - index);
  241. return dest;
  242. }
  243. /**
  244. * 整形数组中特定位置删除掉一个元素,数组中原有元素向前移动; 如果插入位置超出原数组,则抛IllegalArgumentException异常
  245. *
  246. * @param array
  247. * @param index
  248. * @return
  249. */
  250. public static int[] remove(int[] array, int index) {
  251. if (array == null || array.length == 0) {
  252. throw new IllegalArgumentException();
  253. }
  254. if (index > array.length || index <= 0) {
  255. throw new IllegalArgumentException();
  256. }
  257. int[] dest = new int[array.length - 1];
  258. System.arraycopy(array, 0, dest, 0, index - 1);
  259. System.arraycopy(array, index, dest, index - 1, array.length - index);
  260. return dest;
  261. }
  262. /**
  263. * 2个数组合并,形成一个新的数组
  264. *
  265. * @param array1
  266. * @param array2
  267. * @return
  268. */
  269. public static int[] merge(int[] array1, int[] array2) {
  270. int[] dest = new int[array1.length + array2.length];
  271. System.arraycopy(array1, 0, dest, 0, array1.length);
  272. System.arraycopy(array2, 0, dest, array1.length, array2.length);
  273. return dest;
  274. }
  275. /**
  276. * 数组中有n个数据,要将它们顺序循环向后移动k位, 即前面的元素向后移动k位,后面的元素则循环向前移k位,
  277. * 例如,0、1、2、3、4循环移动3位后为2、3、4、0、1。
  278. *
  279. * @param array
  280. * @param offset
  281. * @return
  282. */
  283. public static int[] offsetArray(int[] array, int offset) {
  284. int length = array.length;
  285. int moveLength = length - offset;
  286. int[] temp = Arrays.copyOfRange(array, moveLength, length);
  287. System.arraycopy(array, 0, array, offset, moveLength);
  288. System.arraycopy(temp, 0, array, 0, offset);
  289. return array;
  290. }
  291. /**
  292. * 随机打乱一个数组
  293. *
  294. * @param list
  295. * @return
  296. */
  297. public static List shuffle(List list) {
  298. java.util.Collections.shuffle(list);
  299. return list;
  300. }
  301. /**
  302. * 随机打乱一个数组
  303. *
  304. * @param array
  305. * @return
  306. */
  307. public int[] shuffle(int[] array) {
  308. Random random = new Random();
  309. for (int index = array.length - 1; index >= 0; index--) {
  310. // 从0到index处之间随机取一个值,跟index处的元素交换
  311. exchange(array, random.nextInt(index + 1), index);
  312. }
  313. return array;
  314. }
  315. // 交换位置
  316. private void exchange(int[] array, int p1, int p2) {
  317. int temp = array[p1];
  318. array[p1] = array[p2];
  319. array[p2] = temp;
  320. }
  321. /**
  322. * 对两个有序数组进行合并,并将重复的数字将其去掉
  323. *
  324. * @param a
  325. *            :已排好序的数组a
  326. * @param b
  327. *            :已排好序的数组b
  328. * @return 合并后的排序数组
  329. */
  330. private static List<Integer> mergeByList(int[] a, int[] b) {
  331. // 用于返回的新数组,长度可能不为a,b数组之和,因为可能有重复的数字需要去掉
  332. List<Integer> c = new ArrayList<Integer>();
  333. // a数组下标
  334. int aIndex = 0;
  335. // b数组下标
  336. int bIndex = 0;
  337. // 对a、b两数组的值进行比较,并将小的值加到c,并将该数组下标+1,
  338. // 如果相等,则将其任意一个加到c,两数组下标均+1
  339. // 如果下标超出该数组长度,则退出循环
  340. while (true) {
  341. if (aIndex > a.length - 1 || bIndex > b.length - 1) {
  342. break;
  343. }
  344. if (a[aIndex] < b[bIndex]) {
  345. c.add(a[aIndex]);
  346. aIndex++;
  347. } else if (a[aIndex] > b[bIndex]) {
  348. c.add(b[bIndex]);
  349. bIndex++;
  350. } else {
  351. c.add(a[aIndex]);
  352. aIndex++;
  353. bIndex++;
  354. }
  355. }
  356. // 将没有超出数组下标的数组其余全部加到数组c中
  357. // 如果a数组还有数字没有处理
  358. if (aIndex <= a.length - 1) {
  359. for (int i = aIndex; i <= a.length - 1; i++) {
  360. c.add(a[i]);
  361. }
  362. // 如果b数组中还有数字没有处理
  363. } else if (bIndex <= b.length - 1) {
  364. for (int i = bIndex; i <= b.length - 1; i++) {
  365. c.add(b[i]);
  366. }
  367. }
  368. return c;
  369. }
  370. /**
  371. * 对两个有序数组进行合并,并将重复的数字将其去掉
  372. *
  373. * @param a
  374. *            :已排好序的数组a
  375. * @param b
  376. *            :已排好序的数组b
  377. * @return合并后的排序数组,返回数组的长度=a.length + b.length,不足部分补0
  378. */
  379. private static int[] mergeByArray(int[] a, int[] b) {
  380. int[] c = new int[a.length + b.length];
  381. int i = 0, j = 0, k = 0;
  382. while (i < a.length && j < b.length) {
  383. if (a[i] <= b[j]) {
  384. if (a[i] == b[j]) {
  385. j++;
  386. } else {
  387. c[k] = a[i];
  388. i++;
  389. k++;
  390. }
  391. } else {
  392. c[k] = b[j];
  393. j++;
  394. k++;
  395. }
  396. }
  397. while (i < a.length) {
  398. c[k] = a[i];
  399. k++;
  400. i++;
  401. }
  402. while (j < b.length) {
  403. c[k] = b[j];
  404. j++;
  405. k++;
  406. }
  407. return c;
  408. }
  409. /**
  410. * 对两个有序数组进行合并,并将重复的数字将其去掉
  411. *
  412. * @param a
  413. *            :可以是没有排序的数组
  414. * @param b
  415. *            :可以是没有排序的数组
  416. * @return合并后的排序数组 打印时可以这样: Map<Integer,Integer> map=sortByTreeMap(a,b);
  417. *                 Iterator iterator = map.entrySet().iterator(); while
  418. *                 (iterator.hasNext()) { Map.Entry mapentry =
  419. *                 (Map.Entry)iterator.next();
  420. *                 System.out.print(mapentry.getValue()+" "); }
  421. */
  422. private static Map<Integer, Integer> mergeByTreeMap(int[] a, int[] b) {
  423. Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
  424. for (int i = 0; i < a.length; i++) {
  425. map.put(a[i], a[i]);
  426. }
  427. for (int i = 0; i < b.length; i++) {
  428. map.put(b[i], b[i]);
  429. }
  430. return map;
  431. }
  432. /**
  433. * 在控制台打印数组,之间用逗号隔开,调试时用
  434. *
  435. * @param array
  436. */
  437. public static String print(int[] array) {
  438. StringBuffer sb = new StringBuffer();
  439. for (int i = 0; i < array.length; i++) {
  440. sb.append("," + array[i]);
  441. }
  442. System.out.println("\n"+sb.toString().substring(1));
  443. return sb.toString().substring(1);
  444. }
  445. }</pre><br>
  446. <br>
  447. <pre></pre>
  448. <pre></pre>

Java数组操作工具的更多相关文章

  1. java基础37 集合框架工具类Collections和数组操作工具类Arrays

    一.集合框架工具类:Collections 1.1.Collections类的特点 该工具类中所有的方法都是静态的 1.2.Collections类的常用方法 binarySearch(List< ...

  2. Java 数组

    数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同. Java语言中提供的数组是用来存储固定大小的同类型元素. 你可以声明一个数组变量,如numbers[100 ...

  3. 第5章 Java数组

    1.什么是数组 数组可以想象成一个巨大的盒子,这个盒子里面存放的是同一个数据类型的数据 例如:int[] scores = {78,68,94,93}; 2.如何使用Java中的数组 2.1申明数组 ...

  4. Java 数组基础

    数组 数组(Array):相同类型数据的集合. 定义数组 方式1(推荐,更能表明数组类型) type[] 变量名 = new type[数组中元素的个数]; 比如: int[] a = new int ...

  5. Java数组及其内存分配

    几乎所有的程序设计语言都支持数组.Java也不例外.当我们需要多个类型相同的变量的时候,就考虑定义一个数组.在Java中,数组变量是引用类型的变量,同时因为Java是典型的静态语言,因此它的数组也是静 ...

  6. [转载]Java数组扩容算法及Java对它的应用

    原文链接:http://www.cnblogs.com/gw811/archive/2012/10/07/2714252.html Java数组扩容的原理 1)Java数组对象的大小是固定不变的,数组 ...

  7. Java数组技巧攻略

      Java数组技巧攻略 0.  声明一个数组(Declare an array) String[] aArray = new String[5]; String[] bArray = {" ...

  8. Java数组扩容算法及Java对它的应用

    1)Java数组对象的大小是固定不变的,数组对象是不可扩容的.利用数组复制方法可以变通的实现数组扩容.System.arraycopy()可以复制数组.Arrays.copyOf()可以简便的创建数组 ...

  9. Java数组与vector互转

    Java数组与vector互转 /* Object[] object1 = null ; //数组定义 Vector<Object> object2;//Vector定义 object2 ...

随机推荐

  1. eas之网络互斥功能示手工控制

    public void doMutexService()    {        IMutexServiceControl mutex = MutexServiceControlFactory.get ...

  2. [bzoj4477 Jsoi2015]字符串树 (可持久化trie)

    传送门 Solution 复习下tire( ̄▽ ̄)/ 裸的可持久化tire,我用树剖求了下LCA Code #include <cstdio> #include <cstring&g ...

  3. [Usaco2004 Open]Cube Stacking 方块游戏

    题面:     约翰和贝茜在玩一个方块游戏.编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方柱.    游戏开始后,约翰会给贝茜发出P(1≤P≤100000)个指令.指令有两种 ...

  4. CentOS7 笔记 (一) .NETCore

    安装系统CentOS,虚拟机好麻烦,直接在阿里云开了一个6个月免费的ECS. 熟悉Linux 基本命令 登录,exit,vi ,vim,vi保存关闭,w,ls,mkdir,df,ip addr,修改系 ...

  5. Unity中使用摇杆控制

    Unity中使用摇杆控制 本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/50 ...

  6. 2018ICPC南京

    可能上一次秦皇岛拿了银,有了偶像包袱? 打的时候感觉状态不是很好. 第一题,让你每次将连续一段区间的石头都拿掉.. 然后让你做个博弈. 橘子一顿分析,认为k+1的倍数都是输. 这时,我们以及默认i+1 ...

  7. mysql 7 种 join

    一. select * from A inner join B on A.key = B.key 二. select * from A left join B on A.key = B.key 三. ...

  8. 通用 mapper

    一.为什么需要通用 mapper 插件 通用 mapper 插件可以自动的生成 sql 语句. 虽然 mybatis 有逆向工程,可以直接生成 XxxMapper.xml 文件,但是这种生成的方式存在 ...

  9. POJ 3762 The Bonus Salary!

    The Bonus Salary! Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on PKU. Origi ...

  10. Swift学习——类的定义,使用,继承,构造等(五)

    Swift学习--类的定义,使用.继承,构造等(五) 类的使用说明 1 使用class和类名来创建一个类名,比如: class student 2 类中属性的声明和常量和变量一样,唯一的差别就是他们的 ...