文章目录
注意:荷兰国旗问题和快排的不同在与More值的确定,荷兰国旗取的是length,而快排length-1;
时间复杂度的比较:
快速排序的时间复杂度为 O(nlogn),最坏情况下为 O(n^2)。堆排序的时间复杂度为 O(nlogn),无论最好情况还是最坏情况都是 O(nlogn)。
1.冒泡排序
思想:每次排序找出当次的最大值,所以只需要进行arr.length-1次大的排序,而在每次大的循环中,需要做arr.length-1-i次小的比较,因为已经确定了i个数的位置放在最后面了。
优化:因为排序过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个flag判断元素是否进行过交换。从而减少不必要的比较。
* @Author Mr.Wu
* @Date 2019/6/23 11:30
* @Version 1.0
**/
public class BubbleSort {
public static void main(String[] args) {
int[] arr ={3,9,-1,10,2};
bubbleSort(arr);
System.out.println("排序之后的数组"+ Arrays.toString(arr));
}
public static void bubbleSort(int[] arr){
int temp =0;
boolean flag =false;
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if (arr[j] > arr[j+1]) {
flag= true;
temp = arr[j];
arr[j] =arr[j+1];
arr[j+1] =temp;
}
}
if(!flag){
break; //在一趟排序中,一次交换都没有发生过。则直接退出
}else{
flag =false;
}
}
}
}
2.选择排序
* @Author Mr.Wu
* @Date 2019/6/24 11:09
* @Version 1.0 选择排序。
**/
public class SelectSort {
public static void main(String[] args) {
int [] arr ={3,5,-1,67,6};
selectSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void selectSort(int[] arr){
for (int i = 0 ; i <arr.length-1; i++) {
int minIndex =i;
int min=arr[i];
for (int j = i+1; j <arr.length ; j++) {
if(min>arr[j]){
min=arr[j];
minIndex =j;
}
}
if(minIndex!=i){
arr[minIndex]=arr[i];
arr[i]=min;
}
}
}
}
代码优化之后:
public static void selectionSort(int[] arr){
if(arr==null||arr.length<2){
return;
}
for(int i=0;i<arr.length-1;i++){
int minIndex=i;
for(int j=i+1;j<arr.length;j++){
minIndex=arr[j]<arr[minIndex]?j:minIndex;
}
swap(arr,i,minIndex);
}
}
public static void swap(int[] arr,int i,int j){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
计数排序
时间复杂度是O(n+k),空间复杂度O(n+k)
量大但是范围比较小
- 某大型企业数万名员工年龄排序
- 如何快速得知高考名次
/**
* @Description TODO
* @Author Mr.Wu
* @Date 2020/6/17 21:19
* @Version 1.0
**/
public class CountSort {
public static void main(String[] args) {
int[] arr = {2,4,2,3,7,1,1,0,0,5,6,9,8,7,4,0,9};
int[] result = sort(arr);
System.out.println(Arrays.toString(result));
}
private static int[] sort(int[] arr){
//1.首先开辟一个存放结果的一个数组
int[] result = new int[arr.length];
//2.开辟范围的数组
int[] count = new int[10];
for (int i = 0; i < arr.length; i++) {
count[arr[i]]++;
}
for (int i = 0,j = 0 ; i < count.length; i++) {
//只要桶中还有值,依次取出来。
while(count[i]-- > 0){
result[j++] = i;
}
}
return result;
}
}
优化之后的计数数组
public class CountSort {
public static void main(String[] args) {
int[] arr = {2,4,2,3,7,1,1,0,0,5,6,9,8,7,4,0,9};
int[] result = sort(arr);
System.out.println(Arrays.toString(result));
}
private static int[] sort(int[] arr){
//1.首先开辟一个存放结果的一个数组
int[] result = new int[arr.length];
//2.开辟范围的数组
int[] count = new int[10];
for (int i = 0; i < arr.length; i++) {
count[arr[i]]++;
}
System.out.println(Arrays.toString(count));
//3.获取一个累加数组,累加数组的值就是当前count
for (int i = 1; i < count.length ; i++) {
count[i] = count[i] +count[i-1];
}
System.out.println(Arrays.toString(count));
//4.倒序处理
for (int i = arr.length-1; i >=0 ; i--) {
result[--count[arr[i]]] = arr[i];
}
return result;
}
}
3.基数排序
基数排序属于稳定性排序,是加粗样式效率较高的稳定性排序。同时也是桶排序的扩展。
基本思想:将所有带比较数值统一为同样的位数长度,数位较短的数前面补零。然后从最低位开始,依次进行一次排序,这样从最低位排序一直到最高位排序完成以后,数列就变成了一个有序序列。
* @Author Mr.Wu
* @Date 2019/7/5 9:49
* @Version 1.0
**/
public class RadixSort {
public static void main(String[] args) {
int[] arr ={53,3,542,748,14,214};
radixSort(arr);
}
//基数排序算法。基数排序是使用空间换时间的经典算法。
public static void radixSort(int[] arr){
//1.得到数组中最大的数的位数
int max =arr[0];
for (int i = 1; i < arr.length; i++) {
if(arr[i]>max){
max=arr[i];
}
}
//得到最大数是几位数
int maxLength=(max+"").length();
int[][] bucket = new int[10][arr.length];
//为了记录每个桶中,实际存放了多少个数据,我们定义一个一维数组来记录各个桶的每次放入的数据个数
//bucketElementConts[0],记录的就是bucket[0]桶的放入数据的个数
int[] bucketElementCounts = new int[10];
for (int i = 0,n=1; i < maxLength; i++, n*=10) {
//(针对每个元素的对应位进行排序),第一次是个位,第二次是十位,第三次是百位
for (int j = 0; j <arr.length ; j++) {
int digitOfElement = arr[j] /n %10; //取出每个元素中对应的位数
bucket[digitOfElement][bucketElementCounts[digitOfElement]] =arr[j];
bucketElementCounts[digitOfElement]++;
}
//按照这个桶的顺序(一维数组的下标依次取出数据,放入到原来的数组)
int index =0;
//遍历每一个桶,并将桶中的数据,放入到原数组中去。
for (int k = 0; k <bucketElementCounts.length ; k++) {
//如果桶中有数据,我们才放入到原数组中
if(bucketElementCounts[k]!=0){
//循环该桶即第k个桶(即第k个一维数组),放入。
for (int l = 0; l <bucketElementCounts[k] ; l++) {
arr[index++] =bucket[k][l];
}
}
//第i+1轮处理后,需要将每个bucketElementConunts[k]=0
bucketElementCounts[k]=0;
}
System.out.println("第"+(i+1)+"轮,对数的排序处理arr="+ Arrays.toString(arr));
}
}
}
排序结果如下:
通过计数排序优化后的基数排序:
* @Author Mr.Wu
* @Date 2020/6/17 20:28
* @Version 1.0
**/
public class RadixSort {
public static void main(String[] args) {
int[] arr = {421,240,115,532,305,430,124};
int[] result = sort(arr);
System.out.println(Arrays.toString(result));
}
public static int[] sort(int[] arr){
int[] result = new int[arr.length];
int[] count = new int[10];
for(int i = 0;i < 3;i++){
int division = (int)Math.pow(10,i);
System.out.println(division);
for (int j = 0; j < arr.length; j++) {
int num = arr[j]/division % 10;
System.out.println(num + "");
count[num]++;
}
System.out.println();
System.out.println(Arrays.toString(count));
for (int m = 1; m < count.length ; m++) {
count[m] = count[m] + count[m-1];
}
System.out.println(Arrays.toString(count));
for (int n = arr.length - 1; n >= 0; n--) {
int num = arr[n]/division % 10;
result[--count[num]] = arr[n];
}
System.arraycopy(result,0,arr,0,arr.length);
Arrays.fill(count,0);
}
return result;
}
}
4.归并排序
.归并排序,先分在治,充分利用了递归的思想。
下面是治的示意图:
* @Author Mr.Wu
* @Date 2019/7/2 9:32
* @Version 1.0
**/
public class MergetSort {
public static void main(String[] args) {
int[] arr={8,4,5,7,1,3,6,2};
int[] temp = new int[arr.length];
mergeSort(arr,0,arr.length-1,temp);
System.out.println("归并排序后"+ Arrays.toString(arr));
}
//分开+合并
public static void mergeSort(int[] arr,int left,int right,int[] temp){
if(left<right){
int mid = (left+right)/2;
//向左递归进行分解
mergeSort(arr,left,mid,temp);
//向右递归进行分解
mergeSort(arr,mid+1,right,temp); //最后到了分的最后,然后在归回去,一步一步的合起来
//到合并
merge(arr,left,mid,right,temp);
}
}
/**
* @param mid:中间索引
* @param left:左边有序序列的初始索引
* @param right:右边索引
* @param temp:中转数组
*/
public static void merge(int[] arr,int left ,int mid,int right,int[] temp){
int i = left;
int j =mid+1; //初始化j,右边有序序列的初始索引
int t =0; //指向temp数组的当前索引
//1.先把左右两边(有序)的数据按照规则填充到temp数组,直到左右两边的有序序列,有一边处理完成为止
while (i<=mid&&j<=right){
if(arr[i]<=arr[j]){
temp[t]=arr[i];
i+=1;
t+=1;
}else{
temp[t]=arr[j];
j+=1;
t+=1;
}
}
//2.把有剩余的数据的一遍的数据依次全部填充到temp中
while(i<=mid){
temp[t]=arr[i];
t+=1;
i+=1;
}
while(j<=right){
temp[t]=arr[j];
t+=1;
j+=1;
}
//3.将temp数组的元素拷贝到arr
t=0;
int tempLeft = left;
while(tempLeft<=right){ //第一次合并tempLeft=0,right=1//tempLeft= 2 right =3//tempLeft =0,right=3;
//最后一次tempLeft=0,right =7;
System.out.println("tempLeft="+tempLeft+"right"+right);
arr[tempLeft]=temp[t];
t+=1;
tempLeft+=1;
}
}
}
优化之后 .思路是一样的。将样本量分成两个部分,现将左边和右边分别进行排序。。。merge函数===用两个指针,分别指向,最左边和中间后面一个,然后进行比较。小的就放在临时数组中,然后将指针右移,直到有一个指针移除边界之后,然后在把剩余的数组都拷贝到临时数组中,这样数组就排完序了,然后在将原数组进行替换。
注意:最后这种基于while的运算,不能采用三目运算符。
思路:
归并排序(Merge Sort)是一种稳定的、基于分治思想的排序算法,它的核心思想是将待排序数组划分成若干等长的子数组,对子数组进行排序,最后合并完成整个排序过程。
具体来说,归并排序的过程如下:
分治:将待排序数组递归分成左右两个子数组,直到子数组中只有一个元素。
合并:合并左右两个子数组,使得合并后的数组仍然有序。具体方法是将两个已经有序的子数组合并成一个有序的大数组。
递归结束条件:当待排序数组的长度为1时,递归结束。
public static void mergeSort(int[] arr,int l,int r){
if(l==r){ //终止条件,此时只有一个数,就不用排了。
return;
}
int mid=(l+r)/2;
mergeSort(arr,l,mid);
mergeSort(arr,mid+1,r);
merge(arr,l,mid,r);
}
public static void merge(int[] arr,int l,int mid,int r){
int[] help =new int[r-l+1];
int i=0;
int p1=l;
int p2=mid+1;
while(p1<=mid&&p2<=R){
help[i++]=arr[p1]<arr[p2]?arr[p1++]:arr[p2++];
}
while(p1<mid){
help[i++]=arr[p1++];
}
while(p2<=r){
help[i++]=arr[p2++];
}
for(int i=0;i<help.length;i++){
arr[l+i]=help[i];
}
}
5.快排和堆排
5.1 小和问题(可以由上面的归并排序引出)
思路:
1.其实可以转换成右边比当前数(curr)大的有几个(i)数,此时的小和就是i*curr;
2.然后利用归并排序来进行解决问题。
public class Code_12_smallSum{
public static int smallSum(int[] arr){
if(arr=null||arr.length<2){
return ;
}
return mergeSort(arr,0,arr.length-1);
}
public static int mergeSort(int[] arr,int l ,int r){
if(l==r){
return ;
}
int mid = l+(r-l)>>1; //这种写法是等价于 int mid=(l+r)/2;并且是防溢出的,同时位运算相对于算数运算较快。
//因为每次治的产生的小和都需要加在一起,所以需要写成这样。
return mergeSort(arr,l,mid)+mergeSort(arr,mid+1,r)+merge(arr,l,mid,r);
}
public static int merge(int[] arr,int l,int mid,int r){
int[] help =new int[r-l+1];
int mid =(l+r)/2;
int res = 0;
int p1=l;
int p2=mid+1;
//还是使用两个指针,然后相比较,较小的放入到临时数组中,同时指针向右移动,直到有一边的指针移出,然后将剩余的数组全部放入到临时数组中。
//注意:这里的res;比较两边的值,看右边的值,因为已经是排好序的了。如果左边的这个指针小于右边的指针,那么右边的所有的数都是小和数。需要全部加起来。
while(p1<=mid&&p2<=r){
res +=arr[p1]<arr[p2]?arr[p1]*(r-p2+1):0;
help[i++] = arr[p1]<arr[p2]?arr[p1++]:arr[p2++];
}
while(p1<=m){
help[i++]=arr[p1++];
}
while(p2<=r){
help[i++]=arr[p2++];
}
for(int i=0;i<help.length;i++){
arr[l+i] =help[i];
}
return res;
}
}
5.2 荷兰国旗问题
直接看问题2 ,然后问题1就是2的简化:
思路:
情况1:curr==num的时候直接跳下一个,不管他
情况2: curr<num:将curr与小于区域的下一个数进行交换,然后小于区域向前扩一个位置。curr++,++less;
情况3:curr>num: 将curr与大于区域的上一个数进行交换,然后大于区域向前扩一个位置,然后在判读(这里还需要判断)
当less和more撞上了,整个过程结束。
public static int[] partition(int[] arr,int l,int r,int num){
int less= l-1;
int more =r+1;
int curr=l;
while(curr<more){
if(arr[curr]<num){
swap(arr,++less,curr++); //先将小于区域的前一个位置与curr位置交换,然后当前位置后移一位。主语++i和i++之间的关系
}else if(arr[curr]>num){
swap(arr,--more,curr); //先将大于区域前的一个数与当前位置交换,但是当前位置不变进行判断
}else{
curr++;
}
}
return new int[] {less+1,more-1};
}
public static void swap(int[] arr,int i,int j){
int temp =arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
5.3快速排序(用荷兰国旗问题改进)
思路:选取数组的最后一个为参照。小于区域在左边,等于区域在中间,大于区域在右边。然后返回的是等于区域的位置,然后根据等于区域的位置然后进行递归。(上面比较的时候用了一个index比较好理解,与下面的这种用l代替是一样的。)
注意:几次都含糊不清的地方,while(l<more);
思路:
快速排序采用分治法(Divide and Conquer)的思想,具体过程如下:
选取一个基准点(pivot)作为分界点。可以从数列中随机选取一个数,或者选择数列的第一个数或最后一个数作为基准点。
比基准点小的数放在左边,比基准点大的数放在右边。对于每个元素,比较它和基准点的大小关系,如果比基准点小,则将其放在基准点的左边,否则放在右边。
对左右两边的子数列进行递归排序。递归结束的条件是子数列长度为1或0,此时子数列已经有序。
public static void quickSort(int[] arr,int l,int r){
if(l<r){
//swap(arr,l+(int)(Math.random()*(r-l+1)),r); 如果加上这一段就是随机快排。
int[] p =partition(arr,l,r);//等于区域的位置,p中固定只有两个元素。
quickSort(arr,l,p[0]-1); //对小于区域进行排序,因为最后返回的是相等数的位置,所以需要减一
quickSort(arr,p[1]+1,r); //对大于区域进行排序,同理是相等数的位置,所以需要加+1
}
}
public static int[] partition(int[] arr,int l,int r){
int less=l-1;
int more=r; //因为我们选取的就是最后一个元素,作为比较,所以不参与。右边区域直接到r
while(l<more){ //这里的l相当于上面的index,用来进行遍历使用的。
if(arr[l]<arr[r]){
swap(arr,++less,l++);
}else if(arr[l]>arr[r]){
swap(arr,--more,l);
}else{
l++;
}
}
swap(arr,more,r); //因为最初,最后面的一个元素没有参与比较,那么最后需要进行交换。
return new int[] {less+1,more}; // 我们需要返回一个包含等于区域的起始和结束位置的数组,即return new int[] {less+1,more}。
}
5.4快速排序(最古老的思路,最好还是采用上面一种)
基本思想:快速排序是对冒泡排序的一种改进。它是通过一趟排序将要排序的数据分割成独立的两个部分,其中一部分的所有数据比另外一部分的所有的数据都要小,然后按照此方法对这两部分分别在进行快速排序,整个排序过程可以递归进行,以此来到达整个数据变成有序数列。
* @Author Mr.Wu
* @Date 2019/6/28 10:41
* @Version 1.0
**/
public class QuickSort {
public static void main(String[] args) {
int[] arr={-9,0,32,-78,0,5,-6,-9};
quickSort(arr,0,arr.length-1);
System.out.println("arr="+ Arrays.toString(arr));
}
public static void quickSort(int[] arr,int left,int right){
int l =left;
int r= right;
int pivot = arr[(left+right)/2];
int temp = 0;
//while循环的目的是让比pivot值小放到左边
while(l<r){
//在pivot的左边一直找,找到大于的等于pivot值,才退出下面这个循环。
while(arr[l]<pivot){
l +=1;
}
while(arr[r]>pivot){
r-=1;
}
//如果l>=r说明pivot的左右两的值,已经按照左边全部是小于等于pivot,右边全是是大于等于pivot的值。
if(l>=r){
break;
}
temp = arr[l];
arr[l] =arr[r];
arr[r]=temp;
//如果交换完后,发现这个arr[l] ==pivot值相等--,前移
if(arr[l]==pivot){
r-=1;
}
if(arr[r]==pivot){
l+=1;
}
if(l==r){ //如果l==r,必须l++,r--,否则出现栈溢出。
l+=1;
r-=1;
}
//向左递归
if(left<r){
quickSort(arr,left,r);
}
if(right>l){ //向右递归。
quickSort(arr,l,right);
}
}
}
}
5.5堆排序
堆 和 数组之间的关系图解,点击这里
思路:首先将数组形成一个大根堆,然后将堆顶的数和最后一个数,进行交换,然后调整位置,使剩余的也变成一个大根堆。
左孩子节点 = 父节点2 +1;
右孩子节点 = 父节点2+2;
父节点 = (左(右)孩子节点-1)/2
注意:几次都忘记写在做向下调整的时候,倒数第二步的,index = largest;
参考文章,点击这里
public static void heapSort(int[] arr){
if(arr==null||arr.length<2){
return;
}
for(int i=0;i<arr.length;i++){
heapInsert(arr,i);
}
int heapSize =arr.length;
swap(arr,0,--heapSize); //先和最后一个位置的进行交换,然后继续下面的操作
while(heapSize>0){
heapify(arr,0,heapSize);
swap(arr,0,--heapSize);
}
}
}
//当值变小之后,每次找出最大值,然后向下沉淀
public static void heapify(int[]arr,int index,int heapSize ){
// index位置所在节点的左子节点位置
int left = index * 2 + 1;
// 左子节点不越界
while (left < heapSize) {
// (left+1)为右子节点的下标,如果右子节点不越界 && 左子节点的值 < 右子节点的值
// largest就表示两个子节点中值较大节点在数组中的下标
int largest = left + 1 < heapSize && arr[left] < arr[left + 1] ? left + 1 : left;
// 当前节点的值和较大子节点的值比较,返回较大节点值的下标
largest = arr[index] > arr[largest] ? index : largest;
// 如果是本身较大,则不用下沉,此位置就是最终位置
if (largest == index) {
break;
}
// 较大的不是本身,则和较大的节点交换位置
swap(arr, index, largest);
// 修改当前下标为较大节点的下标
index = largest;
// 找当前下标位置对应的左子节点下标
left = 2 * index + 1;
}
}
//形成大跟堆,每个位置都和它的父亲节点进行对比,如果比父亲节点大就交换位置。
public static void heapInsert(int[] arr,int index){
while(arr[index]>arr[(index-1)/2]){
swap(arr,index,(index-1)/2);
index =(index-1)/2; //这里必须还要往上跑,然后进行比较交换。
}
6.插入排序:
插入排序的基本思想是:把n个待排序的元素看成一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,比较的方式是倒序,也就是先和n-1比较,如果n比n-1小,则互换位置,来到n-1的位置,然后n-1和n-2比,一直比到大于等于即可。(因为前面的元素是排序好的,所以比较一遍即可)
6.1插入排序方法1:(交换法)
/**
* @Description TODO
* @Author Mr.Wu
* @Date 2019/6/26 11:25
* @Version 1.0
**/
public class InsertSort2 {
public static void main(String[] args) {
int[] arr = {101,34,119,1,-1,89};
insertSort(arr);
}
public static void insertSort(int[] arr){
int j ;
for (int i = 1; i <arr.length ; i++) { //需要排序的次数
for ( j = i-1; j>=0&&arr[j]>arr[j+1]; j--) { //取i前面的所有元素和i元素进行比较,如果i-1大于i,则互换位置,以此类推。
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
System.out.printf("第%d次排序之后的结果"+Arrays.toString(arr),i);
System.out.println();
}
}
}
6.2插入排序方法2:(移动法)
* @Description TODO
* @Author Mr.Wu
* @Date 2019/6/25 10:26
* @Version 1.0
**/
public class InsertSort {
public static void main(String[] args) {
int[] arr={101,34,119,1,-1,89};
insertSort(arr);
}
public static void insertSort(int[] arr){
for (int i = 1; i <arr.length ; i++) {
int insertVal=arr[i];
int insertIndex=i-1;
while(insertIndex>=0&&insertVal<arr[insertIndex]){
arr[insertIndex+1]=arr[insertIndex];
insertIndex--;
}
arr[insertIndex+1]=insertVal;
System.out.printf("第%d次排序之后的结果"+Arrays.toString(arr),i);
System.out.println();
}
}
}
结果都如下所示:
第1次排序之后的结果[34, 101, 119, 1, -1, 89]
第2次排序之后的结果[34, 101, 119, 1, -1, 89]
第3次排序之后的结果[1, 34, 101, 119, -1, 89]
第4次排序之后的结果[-1, 1, 34, 101, 119, 89]
第5次排序之后的结果[-1, 1, 34, 89, 101, 119]
7.希尔排序
7.1:采用交换法,进行希尔排序:
* @Author Mr.Wu
* @Date 2019/6/26 14:50
* @Version 1.0
**/
public class ShellSort {
public static void main(String[] args) {
int[] arr = {8,9,1,7,2,3,5,4,6,0};
shellSort(arr);
}
public static void shellSort(int[] arr){
for (int gap = arr.length/2; gap >0 ; gap/=2) { //步长逐渐在减小
for (int i = gap; i <arr.length ; i++) { //在同一步长内,需要排序的次数
//同一步长内排序方式就是插入排序,使用的是第一种
for ( int j = i-gap; j>=0&&arr[j]>arr[j+gap]; j-=gap) {
int temp = arr[j];
arr[j]=arr[j+gap];
arr[j+gap] =temp;
}
}
System.out.printf("步长为%d的排序结果为"+ Arrays.toString(arr),gap);
System.out.println();
}
}
}
7.2采用移动法进行希尔交换
* @Author Mr.Wu
* @Date 2019/6/26 15:40
* @Version 1.0
**/
public class ShellSort2 {
public static void main(String[] args) {
int[] arr = {8,9,1,7,2,3,5,4,6,0};
shellSort2(arr);
}
public static void shellSort2(int[] arr){
for (int gap = arr.length/2; gap >0 ; gap/=2) { //步长逐渐在减小
//从第gap个元素,逐个对其所在的组进行直接插入排序
for (int i = gap; i <arr.length ; i++) {
int j=i; //保存了插入数的位置
int temp =arr[j]; //保存了插入的数
while(j-gap>=0&&temp<arr[j-gap]){
arr[j] =arr[j-gap];
j-=gap;
}
arr[j] =temp;
}
System.out.printf("步长为%d的排序结果为"+ Arrays.toString(arr),gap);
System.out.println();
}
}
}
结果如下:
步长为5的排序结果为[3, 5, 1, 6, 0, 8, 9, 4, 7, 2]
步长为2的排序结果为[0, 2, 1, 4, 3, 5, 7, 6, 9, 8]
步长为1的排序结果为[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
总结:通过验证移动法的效率远高于交换法。