jdk自带的经典算法
排序
private static void binarySort(Object[] a, int lo, int hi, int start) { assert lo <= start && start <= hi; if (start == lo) start++; for (; start < hi; start++) { // 选择start节点的值为锚点 Comparable pivot = (Comparable) a[start]; // 设置次轮循环排序的左节点为lo, 右节点是start,即次轮将数组索引:lo->start排序好 int left = lo; int right = start; assert left <= right; // 锚点pivot的位置,因为之前lo->start-1是排序好,所以通过2分查询找到pivot的位置 // pivot >= all in [lo, left), pivot < all in [right, start). while (left < right) { int mid = (left + right) >>> 1; if (pivot.compareTo(a[mid]) < 0) right = mid; else left = mid + 1; } assert left == right; // 计算数组需要移动的个数,把pivot放到left的位置,后续位置往后挪动一位:left->start-1===>left+1->start int n = start - left; // 优化挪动算法 switch (n) { case 2: a[left + 2] = a[left + 1]; case 1: a[left + 1] = a[left]; break; default: System.arraycopy(a, left, a, left + 1, n); } // 将pivot放到left的位置 a[left] = pivot; } }
自己练习的版本
1 public static void timSort(Integer[] a) { 2 int len = a.length; 3 int low = 0; 4 if (a.length <= 1) { 5 return; 6 } 7 int count = 0; 8 for (int start = 1; start < len; start++) { 9 int left = low; 10 int right = start; 11 int pivot = a[start]; 12 while (left < right) { 13 count++; 14 int mid = right + left >>> 1; 15 if (pivot < a[mid]) { 16 right = mid; 17 } else { 18 left = mid + 1; 19 } 20 } 21 int n = start - left; 22 System.arraycopy(a, left, a, left + 1, n); 23 a[left] = pivot; 24 } 25 System.out.println("count:" + count); 26 }
字符串查找
1 static int indexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex) { 2 if (fromIndex >= sourceCount) { 3 return (targetCount == 0 ? sourceCount : -1); 4 } 5 if (fromIndex < 0) { 6 fromIndex = 0; 7 } 8 if (targetCount == 0) { 9 return fromIndex; 10 } 11 // 需要查找的第一个字符 12 char first = target[targetOffset]; 13 int max = sourceOffset + (sourceCount - targetCount); 14 15 for (int i = sourceOffset + fromIndex; i <= max; i++) { 16 /* Look for first character. */ 17 if (source[i] != first) { 18 while (++i <= max && source[i] != first); 19 } 20 21 /* Found first character, now look at the rest of v2 */ 22 if (i <= max) { 23 int j = i + 1; 24 int end = j + targetCount - 1; 25 for (int k = targetOffset + 1; j < end && source[j] 26 == target[k]; j++, k++); 27 28 if (j == end) { 29 /* Found whole string. */ 30 return i - sourceOffset; 31 } 32 } 33 } 34 return -1; 35 }
自己的练习版本
private static int findStringIndex(String source, String target) { if (StringUtils.isBlank(source) || StringUtils.isBlank(target)) { return -1; } char[] sourceChars = source.toCharArray(); char[] targetChars = target.toCharArray(); int max = sourceChars.length - target.length(); for (int i = 0; i <= max; i++) { if (sourceChars[i] != targetChars[0]) { while (i++ < max && sourceChars[i] != targetChars[0]) ; } // 从第二个字符串查找 if (i <= max) { int j = i + 1; int end = j + targetChars.length - 1; for (int k = 1; j < end && sourceChars[j] == targetChars[k]; j++, k++); if (j == end) { /* Found whole string. */ return i; } } } return -1; }