直接上代码:思想都在注释里,领悟都在代码中。
public class Sort { //插入排序 //思想:不是假定,是真的i前面部分变成有序,通过一步步插入方式排好的序,循环的是要找位置插入的剩余元素!! public static int[] insertionSort(int[] A,int n){ int i,j,temp; for(i=1;i<n;i++){ temp=A[i]; j=i-1; while(j>=0){ if(temp<A[j]){ A[j+1]=A[j]; }else{ break;//必须结束循环!因为找到这个位置了!! } j--; } A[j+1]=temp; } return A; } //选择排序 //思想:遍历,每次选一个最小的,前面i个通过寻找最小值排好序 public static int[] selectionSort(int[] A,int n){ for(int i=0;i<n;i++){ int min=i;//排好序部分的末尾 for(int j=i+1;j<n;j++){ if(A[j]<A[min]){ min=j; } } //注意交换a[i]和a[min]使剩余序列的最小元素交-换-到已排序部分末尾 int temp=A[min]; A[min]=A[i]; A[i]=temp; } return A; } //冒泡排序 //思想:每次遍历,如果相邻元素逆序,交换,这样最大的出现在末尾,以此从尾部削减每次遍历元素数 //要想最小的元素出现的起始,那得从后往前遍历,也是小在前大在后 public static int[] bubbleSort(int[] A,int n){ for(int i=0;i<n-1;i++){ for(int j=0;j<n-i-1;j++){//每次后面的部分已排好序 if(A[j]>A[j+1]){ int temp=A[j]; A[j]=A[j+1]; A[j+1]=temp; } } } return A; } //优化1 //思想:设置一个标记,每次遍历初始都设为false,如果某一趟发生了哪怕一次交换就置为true,以此为判断条件,如果到了某一趟没有一次交换,标记为false,那么提前结束循环!! public static int[] bubbleSort2(int[] A,int n){ boolean flag; flag=true; while(flag){//外层循环是通过flag控制的,每次缩小规模是靠n-- flag=false; for(int j=0;j<n-1;j++){ if(A[j]>A[j+1]){ int temp=A[j]; A[j]=A[j+1]; A[j+1]=temp; flag=true; } } n--; } return A; } //优化2 //思想:每次遍历,缩小规模的尺度。每次记住最后发生交换的位置,那么这位置后面的都已经有序了,直接跳到该位置!! public static int[] bubbleSort3(int[] A,int n){ int k; int flag;//每次最后交换发生的位置 flag=n;//初始设置为n while(flag>0){//以flag>0判断!! k=flag;//k每次跳-跃-缩-减-规-模,至上一次flag记录(其后的元素因为再没发生交换而说明已经排序) flag=0; for(int j=0;j<k-1;j++){ if(A[j]>A[j+1]){ int temp=A[j]; A[j]=A[j+1]; A[j+1]=temp; flag=j+1;//记录最后交换的下标!! } } } return A; } //希尔排序 //思想:以一组增量多次分组,最后是增量为1每组一个元素,即要排序的序列本身。组元素个数逐步缩减为1, //不是组内元素进行排序,而是组内的每个元素以组元素个数为跳跃(增量),在组间插入排序。根据书,排序后的顺序不变,组元素个数逐步缩减为1时,每个元素都排序了。 public static int[] shellSort1(int A[],int n){ int i,j,gap; for(gap=n/2;gap>0;gap/=2){//增量序列,每次以此为增量分组,直至每组元素个数为1 for(i=0;i<gap;i++){//第一组中的元素,gap个元素中的每一个都需要以gap为步长,在组间进行插入排序 for(j=i+gap;j<n;j+=gap){//gap才是步长!对第一组中的元素以gap为增量在整个序列范围寻找元素进行插入排序 if(A[j]<A[j-gap]){ //这里才到了为单个元素寻找位置(当然,是以gap为步长)的插入排序,while循环是寻找位置 int temp=A[j]; int k=j-gap; while(k>=0 && A[k]>temp){ A[k+gap]=A[k]; k-=gap; } A[k+gap]=temp; } } } } return A; } //希尔排序:书上的和网上所谓改进的做法 //思想:第一组以后的每个元素以gap为步长插入到合适的位置,相当于网上两个内循环的第一组的每个元素以gap为步长进行插入排序!! public static int[] shellSort2(int A[],int n){ int i,j,gap; for(gap=n/2;gap>0;gap/=2){ for(i=gap;i<n;i++){ int temp=A[i]; for(j=i;j>=gap && temp<A[j-gap];j-=gap)//以gap为步长,挪元素找位置 A[j]=A[j-gap]; A[j]=temp; } } return A; } public static String arrayToString(int[] A){ StringBuilder builder=new StringBuilder(); builder.append('['); for(int i=0;i<A.length;i++){ if(i>0) builder.append(','); builder.append(A[i]); } builder.append(']'); return builder.toString(); } public static void main(String[] args) { int[] A={2,456,4,576,2235,8,235,87,323,976,24,8,2,1,87,569}; System.out.println(arrayToString(insertionSort(A,A.length))); System.out.println(arrayToString(selectionSort(A,A.length))); System.out.println(arrayToString(bubbleSort(A,A.length))); System.out.println(arrayToString(bubbleSort2(A,A.length))); System.out.println(arrayToString(bubbleSort3(A,A.length))); System.out.println(arrayToString(shellSort1(A,A.length))); System.out.println(arrayToString(shellSort2(A,A.length))); } }
D:\java\practice9>javac Sort.java
D:\java\practice9>java Sort
[1,2,2,4,8,8,24,87,87,235,323,456,569,576,976,2235]
[1,2,2,4,8,8,24,87,87,235,323,456,569,576,976,2235]
[1,2,2,4,8,8,24,87,87,235,323,456,569,576,976,2235]
[1,2,2,4,8,8,24,87,87,235,323,456,569,576,976,2235]
[1,2,2,4,8,8,24,87,87,235,323,456,569,576,976,2235]
[1,2,2,4,8,8,24,87,87,235,323,456,569,576,976,2235]
[1,2,2,4,8,8,24,87,87,235,323,456,569,576,976,2235]