排序
内部排序
插入排序
选择排序
交换排序
直接插入排序
给定一组序列,假定第一个记录自成一个有序序列,其余记录为无序序列。接着从第二个记录开始,按照记录的大小依此将当前处理的记录插入到其之前的有序序列中,直到最后一个记录插入到有序序列中为止
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
| public static void insertSort(int arr[]){ if(arr == null || arr.length ==0){ return ; } int j = 0; for(int i = 1;i<arr.length;i++){ int temp = arr[i]; j = i; if(temp < arr[j=1]){ do{ arr[j] = arr[j-1]; j--; }while(arr[j]>temp && j>=1);
arr[j] = temp; } }
}
|
1 2 3 4
| 排序前: 38 65 97 76 13 27 49 排序后: 13 27 38 49 65 76 97
|
希尔排序(最小增量排序)
算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public static void shellSort(int arr[]){ int length = arr.length; for(int h = length/2;h>0;h=h/2){ for(int i = 0;i<length-h;i++){ int temp ; if(arr[i+h]<arr[i]){ temp = arr[i+h]; arr[i+h] = arr[i]; arr[i] = temp; } } } }
|
1 2 3 4
| 排序前: 38 65 97 76 13 27 49 shell排序后: 13 27 38 49 65 76 97
|
简单选择排序
在要排序的一组数中,选出最小的一个数与第一个位置的数交换;
然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public static void selectSort(int arr[]){ int minLocation = 0; for(int i = 0;i<arr.length;i++){ int temp = arr[i]; for(int j = i+1;j<arr.length;j++){ if(temp > arr[j]){ temp = arr[j]; minLocation = j; } } if(minLocation != i){ arr[minLocation] = arr[i]; arr[i] = temp; } } }
|
1 2 3 4
| 排序前: 38 65 97 76 13 27 49 选择排序后: 13 27 38 49 65 76 97
|
堆排序
堆排序是一种树形选择排序,是对直接选择排序的有效改进。
冒泡排序
在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public static void bubbleSort(int[] arr){ int i; int j; int temp = 0;
for ( i = 0; i < arr.length; i++) { for(j = arr.length-1;j>i;j--){ if(arr[j-1] > arr[j]){ temp = arr[j]; arr[j] = arr[j-1]; arr[j-1] = temp; }
} } }
|
1 2 3 4
| 排序前: 38 65 97 76 13 27 49 21 5 8 6 4 8 3 9 冒泡排序后: 3 4 5 6 8 8 9 13 21 27 38 49 65 76 97
|
快速排序
快速排序是一种非常高效的排算法,它采用了分而治之
的思想,把大的拆成小的,小的再拆分为更小的
基本思想:选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。
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
| public static void quickSort(int []arr){ sort(arr, 0, arr.length-1);
}
private static void sort(int arr[],int low,int high){ if(low>=high) return; int i = low; int j = high; int key = arr[low]; while(j>i){
while(j>i && key <= arr[j]){ j--; } if(arr[j]<=key){ int temp = arr[j]; arr[j] = arr[i]; arr[i] = temp; }
while(j>i && key >= arr[i]){ i++; } if(arr[i]>=key){ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } sort(arr, low, i-1); sort(arr,j+1,high); }
|
1 2 3 4
| 排序前: 38 65 97 76 13 27 49 21 5 8 6 4 8 3 9 58 66 75 22 93 91 10 冒泡排序后: 3 4 5 6 8 8 9 10 13 21 22 27 38 49 58 65 66 75 76 91 93 97
|
并归排序
并归排序的思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
使用技术: 递归
和 分治
先拆分再组合
并归时排序,采用双指针分别指向左半边和右半边,左半边的和有半边的比较大小,小的一边存入新的数组并自增
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
| public static void mergeSort(int []arr,int low,int high){ if(low < high){ int mid = (low+high)/2; mergeSort(arr, low, mid); mergeSort(arr, mid+1, high); merge(arr, low, mid, high); } } private static void merge(int arr[],int low,int mid,int high){ int temp[] = new int [high-low+1]; int left = low; int right = mid + 1; int indexOfTemp = 0;
while(left<=mid && right<=high){ if(arr[left] < arr[right]){ temp[indexOfTemp++] = arr[left++]; }else{ temp[indexOfTemp++] = arr[right++]; } }
while(left <= mid){ temp[indexOfTemp++] = arr[left++]; } while(right <= high){ temp[indexOfTemp++] = arr[right++]; } for(int i = 0;i<temp.length;i++){ arr[low + i] = temp[i]; } }
|
1 2 3 4
| 排序前: 58 66 75 22 93 91 10 16 52 18 90 77 44 29 并归排序后: 10 16 18 22 29 44 52 58 66 75 77 90 91 93
|