冒泡排序
/** * 排序器接口(策略模式:将算法封装到具有共同接口的独立的类中,使得他们可以相互替换) * @author Silence * */ public interface Sorter { /** * 排序 * @param list 待排序的数组 */ public <T extends Comparable<T>> void sort(T[] list); /** * 排序 * @param list 待排序的数组 * @param comp 比较两个对象的比较器 */ public <T> void sort(T[] list, Comparator<T> comp); }
/** * 冒泡排序 * * @author Silence * */ public class BubbleSorter implements Sorter { @Override public <T extends Comparable<T>> void sort(T[] list) { boolean swapped = true; for (int i = 1; i < list.length && swapped; ++i) { swapped = false; for (int j = 0; j < list.length - i; ++j) { if (list[j].compareTo(list[j + 1]) > 0) { T temp = list[j]; list[j] = list[j + 1]; list[j + 1] = temp; swapped = true; } } } } @Override public <T> void sort(T[] list, Comparator<T> comp) { boolean swapped = true; for (int i = 1; i < list.length && swapped; ++i) { swapped = false; for (int j = 0; j < list.length - i; ++j) { if (comp.compare(list[j], list[j + 1]) > 0) { T temp = list[j]; list[j] = list[j + 1]; list[j + 1] = temp; swapped = true; } } } } @Test public void testSorter(){ Integer[] nums = { 1, 3, 5, 12, 6, 15, 7 }; // sort(nums); sort(nums, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o2 - o1; } }); for (Integer integer : nums) { System.out.println(integer); } } }
二分查找
public class MyUtil { // 工具类中的方法都是静态方式访问的因此将构造器私有不允许创建对象(绝对好习惯) private MyUtil() { throw new AssertionError(); } public static <T extends Comparable<T>> int binarySerarch(T[] x, T key) { return binarySearch(x, 0, x.length - 1, key); } /* 说明:下面的代码中给出了折半查找的两个版本,一个用递归实现,一个用循环实现。需要注意的是计算 中间位置时不应该使用(high+ low) / 2 的方式,因为加法运算可能导致整数越界,这里应该使用以下三种方 式之一:low + (high - low) / 2 或 low + (high – low) >> 1 或(low + high) >>> 1(>>>是逻辑右移,是不带符号 位的右移) */ /** * 使用循环实现的二分查找 * @param x * @param key * @return */ public static <T> int binarySerarch(T[] x, T key, Comparator<T> comp) { int low = 0; int high = x.length - 1; while(low <= high){ int mid = (low + high) >>> 1; int cmp = comp.compare(x[mid], key); if (cmp < 0) { low = mid + 1; }else if (cmp > 0) { high = mid - 1; }else { return mid; } } return -1; } /** * 使用递归实现的二分查找 */ private static <T extends Comparable<T>> int binarySearch(T[] x, int low, int high, T key) { if (low <= high) { int mid = low + (high - low) >> 1; if (key.compareTo(x[mid]) == 0) { return mid; } else if (key.compareTo(x[mid]) < 0) { return binarySearch(x, low, mid - 1, key); } else { return binarySearch(x, mid + 1, high, key); } } return -1; } }
public class BinarySerarch { @Test public void binarySearchTest() { Integer[] nums = { 1, 2, 3, 5, 6, 15, 18, 20, 25, 34, 9 }; int index = MyUtil.binarySerarch(nums, 15); System.out.println("index:" + index);// index:5 } }
快速排序:https://www.cnblogs.com/hjy9420/p/5032309.html
快速排序的原理:选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序的),比基准值大的都在右边(一般是无序的)。一般选择序列的第一个元素。
一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有继续比较下一个,直到找到第一个比基准值小的值才交换。找到这个值之后,又从前往后开始比较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的值才交换。直到从前往后的比较索引>从后往前比较的索引,结束第一次循环,此时,对于基准值来说,左右两边就是有序的了。
接着分别比较左右两边的序列,重复上述的循环。
1 public class FastSort{ 2 3 public static void main(String []args){ 4 System.out.println("Hello World"); 5 int[] a = {12,20,5,16,15,1,30,45,23,9}; 6 int start = 0; 7 int end = a.length-1; 8 sort(a,start,end); 9 for(int i = 0; i<a.length; i++){ 10 System.out.println(a[i]); 11 } 12 13 } 14 15 public void sort(int[] a,int low,int high){ 16 int start = low; 17 int end = high; 18 int key = a[low]; 19 20 21 while(end>start){ 22 //从后往前比较 23 while(end>start&&a[end]>=key) //如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较 24 end--; 25 if(a[end]<=key){ 26 int temp = a[end]; 27 a[end] = a[start]; 28 a[start] = temp; 29 } 30 //从前往后比较 31 while(end>start&&a[start]<=key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置 32 start++; 33 if(a[start]>=key){ 34 int temp = a[start]; 35 a[start] = a[end]; 36 a[end] = temp; 37 } 38 //此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用 39 } 40 //递归 41 if(start>low) sort(a,low,start-1);//左边序列。第一个索引位置到关键值索引-1 42 if(end<high) sort(a,end+1,high);//右边序列。从关键值索引+1到最后一个 43 } 44 45 }