直接上代码:思想都在注释里,领悟都在代码中。
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]