歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 最壞情況線性時間的選擇 Java實現

最壞情況線性時間的選擇 Java實現

日期:2017/3/1 10:38:47   编辑:Linux編程

最壞情況線性時間的選擇 Java實現:

  1. package ctgu.sugite.content.character09;
  2. import java.util.Arrays;
  3. import java.util.Random;
  4. public class WorstLinearSelect {
  5. public static void main(String[] args) {
  6. int n = 34, k = 7;/* 34個元素中找出第7小的元素 */
  7. int[] a = new int[n];
  8. Random rd = new Random();
  9. for (int i = 0; i < n; i++) {
  10. a[i] = rd.nextInt(100);
  11. }
  12. System.out.println(Arrays.toString(a));
  13. System.out.println(select(a, 0, n - 1, k));/* 進行線性查找 */
  14. Arrays.sort(a);
  15. System.out.println(Arrays.toString(a));/* 排序後輸出,進行驗證 */
  16. }
  17. private static int select(int[] a, int law, int high, int k) {
  18. if (high - law < 5) {
  19. insertSort(a, law, high);
  20. return a[law + k - 1];
  21. }
  22. int teams = (high - law + 5) / 5;// 組數
  23. for (int i = 0; i < teams; i++) {
  24. /* 第一步:將輸入數組的n個元素劃分為n/5組,每組5個元素,且至多只有一個組由剩下的n mod5個元素組成 */
  25. int left = law + i * 5;
  26. int right = (law + i * 5 + 4) > high ? high : law + i * 5 + 4;
  27. int mid = (left + right) / 2;
  28. /* 第二步:尋找(n+4)/5個組中每一組的中位數。首先對每組中的元素(至多為5個)進行插入排序,然後從排序過的序列中選出中位數 */
  29. insertSort(a, left, right);
  30. swap(a, law + i, mid);// 將中位數置前
  31. }
  32. /* 第三步:對第二步中找出的(n+4)/5個中位數,遞歸調用select以找出其中位數x */
  33. int pivot = select(a, law, law + teams - 1, (teams + 1) / 2);
  34. /* 第四步:利用修改過的partition過程,按中位數的中位數x對輸入數組進行劃分 */
  35. int pos = partition(a, law, high, pivot);
  36. /* 第五步:判斷pos位置是否為要找的數,若不是則在低區或者高區遞歸select */
  37. int leftNum = pos - law;
  38. if (k == leftNum + 1)
  39. return a[pos];
  40. else if (k <= leftNum)
  41. return select(a, law, pos - 1, k);
  42. else
  43. return select(a, pos + 1, high, k - leftNum - 1);
  44. }
  45. private static int partition(int[] a, int law, int high, int pivot) {
  46. int index = law;
  47. for (int i = law; i <= high; i++) {
  48. if (a[i] == pivot) {
  49. index = i;
  50. break;
  51. }
  52. }/* 找到樞紐的位置 */
  53. swap(a, index, high);
  54. int i = law - 1;
  55. for (int j = law; j < high; j++) {
  56. if (a[j] <= pivot) {
  57. swap(a, j, ++i);
  58. }
  59. }
  60. swap(a, high, ++i);
  61. return i;
  62. }
  63. private static void swap(int[] a, int i, int j) {
  64. int temp = a[i];
  65. a[i] = a[j];
  66. a[j] = temp;
  67. }
  68. /* 插入排序 */
  69. private static void insertSort(int[] a, int law, int high) {
  70. for (int i = law + 1; i <= high; i++) {
  71. int key = a[i];
  72. int j = i - 1;
  73. while (j >= law && a[j] > key) {
  74. a[j + 1] = a[j];
  75. j--;
  76. }
  77. a[j + 1] = key;
  78. }
  79. }
  80. }
Copyright © Linux教程網 All Rights Reserved