标签:需要 printf 分治 play lease block scan 直接 i++
一、选择排序法
简单选择排序是最简单直观的一种算法,基本思想为每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,简单选择排序是不稳定排序。
for (int i = 0; i < arr.length - 1; i++) {
int min = i;//每一趟循环比较时,min用于存放较小元素的数组下标,这样当前批次比较完毕最终存放的就是此趟内最小的元素的下标,避免每次遇到较小元素都要进行交换。 for (int j = i + 1; j < arr.length; j++) { if (arr[j] < arr[min]) { min = j; } }
}
简单选择排序通过上面优化之后,无论数组原始排列如何,比较次数是不变的;对于交换操作,在最好情况下也就是数组完全有序的时候,无需任何交换移动,在最差情况下,也就是数组倒序的时候,交换次数为n-1次。综合下来,时间复杂度为
)
二、冒泡排序
冒泡排序的基本思想是,对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序
for (int i = 0; i < arr.length - 1; i++) { boolean flag = true;//设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已然完成。 for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1]) { swap(arr,j,j+1); flag = false; } } if (flag) { break; } }
根据上面这种冒泡实现,若原数组本身就是有序的(这是最好情况),仅需n-1次比较就可完成;若是倒序,比较次数为 n-1+n-2+
...
+1=n(n-1)/2,交换次数和比较次数等值。所以,其时间复杂度依然为O(n
2
)。综合来看,冒泡排序性能还还是稍差于上面那种选择排序的。
三、插入排序
直接插入排序基本思想是每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。
for (int i = 1; i < arr.length; i++) { int j = i; while (j > 0 && arr[j] < arr[j - 1]) { swap(arr,j,j-1); j--; } }
简单插入排序在最好情况下,需要比较n-1次,无需交换元素,时间复杂度为O(n);在最坏情况下,时间复杂度依然为O(n2)。但是在数组元素随机排列的情况下,插入排序还是要优于上面两种排序的。
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
public class ShellSort { 9 public static void main(String []args){ 10 int []arr ={1,4,2,7,9,8,3,6}; 11 sort(arr); 12 System.out.println(Arrays.toString(arr)); 13 int []arr1 ={1,4,2,7,9,8,3,6}; 14 sort1(arr1); 15 System.out.println(Arrays.toString(arr1)); 16 } 17 18 /** 19 * 希尔排序 针对有序序列在插入时采用交换法 20 * @param arr 21 */ 22 public static void sort(int []arr){ 23 //增量gap,并逐步缩小增量 24 for(int gap=arr.length/2;gap>0;gap/=2){ 25 //从第gap个元素,逐个对其所在组进行直接插入排序操作 26 for(int i=gap;i<arr.length;i++){ 27 int j = i; 28 while(j-gap>=0 && arr[j]<arr[j-gap]){ 29 //插入排序采用交换法 30 swap(arr,j,j-gap); 31 j-=gap; 32 } 33 } 34 } 35 } 36 37 /** 38 * 希尔排序 针对有序序列在插入时采用移动法。 39 * @param arr 40 */ 41 public static void sort1(int []arr){ 42 //增量gap,并逐步缩小增量 43 for(int gap=arr.length/2;gap>0;gap/=2){ 44 //从第gap个元素,逐个对其所在组进行直接插入排序操作 45 for(int i=gap;i<arr.length;i++){ 46 int j = i; 47 int temp = arr[j]; 48 if(arr[j]<arr[j-gap]){ 49 while(j-gap>=0 && temp<arr[j-gap]){ 50 //移动法 51 arr[j] = arr[j-gap]; 52 j-=gap; 53 } 54 arr[j] = temp; 55 } 56 } 57 } 58 } 59 /** 60 * 交换数组元素 61 * @param arr 62 * @param a 63 * @param b 64 */ 65 public static void swap(int []arr,int a,int b){ 66 arr[a] = arr[a]+arr[b]; 67 arr[b] = arr[a]-arr[b]; 68 arr[a] = arr[a]-arr[b]; 69 } 70 }
标签:需要 printf 分治 play lease block scan 直接 i++
原文地址:https://www.cnblogs.com/lumc5/p/11245229.html