冒泡算法
每次遍历进行i与i+1的值进行比较,把大的值都往数组后面丢,保证了数组末尾的元素为最大。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public static int[] test1(int[] arr) { int temp; for(int i=arr.length-1;i>0;i--) { for(int j=0;j<i;j++) { if (arr[j] > arr[j+1]) { temp = arr[j+1]; arr[j+1] = arr[j]; arr[j] = temp; } } } System.out.println(change(arr)); return arr; }
|
选择算法
对于冒泡是同个理念,不过减少了交换的次数。从左往右遍历,基于左边界的值进行比较,找到最小的元素进行替换,保证左边界的值是最小的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static void test2(int[] arr) { int temp; for (int i = 0; i < arr.length - 1; i++) { for (int j = i+1; j < arr.length; j++) { if(arr[i] > arr[j]) { temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } System.out.println(change(arr)); }
|
插入算法
从左往右,每次都以i+1为右边界,然后i+1的元素需要插入已经排好序的[0,i]的数组里,从后面一直比较到前面,遍历从i到0,只要有元素大于i+1那个元素就交换,最后插入成功后[0,i+1]就是排好序的数组了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static void test3(int[] arr) { int temp; for (int i = 0; i < arr.length - 1; i++) { for (int j = i+1; j > 0; j--) { if(arr[j-1] > arr[j]) { temp = arr[j-1]; arr[j-1] = arr[j]; arr[j] = temp; } } } System.out.println(change(arr)); }
|
希尔排序
缩小增量排序,每次都以rightStart=k为右边界的开始遍历,然后以比较0+k与k+k的方式遍历数组,前者大于后者就替换,直到k=0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public static void test4(int[] arr) { int temp; int k = arr.length/2; while (k != 0) { for (int rightStart = k; rightStart < arr.length; rightStart++) { int left = rightStart - k; int right = rightStart; while (right < arr.length) { if(arr[left] > arr[right]) { temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; } left += k; right += k; } } k /= 2; } System.out.println(change(arr)); }
|
归并算法
把大数组拆分成小数组不断进行比较排序得到最终结果。比如{1,2,3,4} => {1,2},{3.4} => {1}, {2},{3},{4}。
每次比较都需要新建一个临时一样大小的数组用来转比较结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public static void test51(int[] arr) { test52(arr, 0, arr.length - 1); System.out.println(change(arr)); }
public static void test52(int[] arr, int left, int right) { if(left == right) { return; } int mid = (right + left) / 2; test52(arr, left, mid); test52(arr, mid + 1, right); test53(arr, left, mid, right); }
public static void test53(int[] arr, int left, int mid, int right) { int leftIndex = left; int rightIndex = mid + 1; int[] tempArr = new int[right - left + 1]; int tempIndex = 0; while(leftIndex <= mid && rightIndex <= right) { if(arr[leftIndex] < arr[rightIndex]) { tempArr[tempIndex++] = arr[leftIndex++]; } else { tempArr[tempIndex++] = arr[rightIndex++]; } }
while (leftIndex <= mid) { tempArr[tempIndex++] = arr[leftIndex++]; } while (rightIndex <= right) { tempArr[tempIndex++] = arr[rightIndex++]; } tempIndex = 0; for (int i = left;i<=right;i++) { arr[i] = tempArr[tempIndex++]; } }
|
快速排序
思想跟归并是差不多的,都是分治。快排都会以左边界的元素为参照物,然后把比它小的往左边丢,大的就往右边丢。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| public static void test61(int[] arr) { test62(arr, 0, arr.length - 1); System.out.println(change(arr)); }
public static void test62(int[] arr,int left, int right) { if(left >= right) { return; } int referenceIndex = left; int reference = arr[left];
int endIndex = right;
int temp; int tempIndex = left; while (left < right) {
while (left < right && arr[right] >= reference) { right--; }
while (left < right && arr[left] <= reference) { left++; }
if(arr[left] > reference && arr[right] < reference) { temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; } if(left == right) { tempIndex = left; } } temp = arr[referenceIndex]; arr[referenceIndex] = arr[tempIndex]; arr[tempIndex] = temp;
test62(arr, referenceIndex, tempIndex); test62(arr, tempIndex+1, endIndex);
}
|