多种排序方法

快速排序

package qicksort;

import java.util.Arrays;

public class QuickSort {
    public static void main(String[] args) {
        int []arr=new int[] {1,4,5,3,6,8,7};
        sort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    public static void sort(int[]arr,int begin,int end) {
        int left=begin;
        int right=end;
        while(left<right) {
            if(arr[left]>arr[left+1]) {
                int temp=arr[left];
                arr[left]=arr[left+1];
                arr[left+1]=temp;
                left++;
            }else {
                int temp=arr[right];
                arr[right]=arr[left+1];
                arr[left+1]=temp;
                right--;
            }
        }
        if(begin<left-1) {
            sort(arr,begin,left-1);
        }
        if(end>left+1) {
            sort(arr,left+1,end);
        }
    }
}
 

插入排序

认为数组中第一个位置是已经排好序的数组,然后用一个游标 i 指向第二个位置,定义游标 j=i-1,令j 和 j+1进行比较并不断前移依次和已排好序的数组中的数据进行比较,将其有序插入到已排好序数组中。

package com.sort;

import java.util.Arrays;

public class InsertSort {
    public static void main(String[] args) {
        int[] arr = new int[] {5,7,4,2,0,3,1,6,9,8};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }    
    public static void sort(int[] arr) {
        for(int i=1;i<arr.length;i++) {
            for(int j=i-1;j>=0;j--) {
                if(arr[j]>arr[j+1]) {
                    int temp = arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                    
                }else {
                    break;
                }
            }
        }
    }
}
 

冒泡排序

1、比较相邻的元素,如果第一个比第二个大,则交换两者。

2、每一轮都对每对相邻元素做比较交换,这样每轮结束,都会有一个最大数被排出来。

3、根据无序数组的长度选择轮数。

4、经过j轮后,排序完成,将无序数组排序成从小到大输出的有序数组。

package com.sort;

import java.util.Arrays;
public class DubbleSort {
    public static void main(String[] args) {
        int[]arr = new int[] {5,7,4,2,0,3,1,6,9,8};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void sort(int[] arr) {
        for(int j=0;j<arr.length;j++) {
            for(int i=0;i+1<arr.length;i++) {
                if(arr[i]>arr[i+1]) {
                    int temp=arr[i];
                    arr[i]=arr[i+1];
                    arr[i+1]=temp;
                }
            }
        }
    }    
}

//选择排序

找到最小值和待排序数组第一个交换。

假设待排序数组第一个就是最小值,之后从前到后去找有没有更小的,找到真正的最小值替代待排序数组第一的位置。

创建区域记录数组第一个的值和地址。每找到更小值时,用真正最小值将值代替,用真正最小值的地址将第一个值的地址代替。最后找到最小值时,将待排序数组第一的位置和真正的最小值进行交换。

package com.sort;

import java.util.Arrays;

public class SearchSort {
    public static void main(String[] args) {
        int[] arr = new int[] {5,7,4,2,0,3,1,6,9,8};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }

public static void sort(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;
            }
        }
        arr[minIndex]=arr[i];
        arr[i]=min;
        }
    }
}
 

基数排序1

基数排序又称“桶子法”、“桶排序”。分别通过将数据的个位、十位、百位……放入桶中,然后取出数据,经过将数据的各位都放入桶中再取出,即可将数据有序排列。需要一个桶记录器来记录每个位数值上有几个数据存入,并且取出时,通过判断桶记录器是否为0即可判断每个位数值里有没有数,如果有数,在按顺序取出。为了确保各个位数的排序不受其他位数排序的影响,每个位数排序完成后需要将桶记录器清空,即重新计数,在取出时,也之会取出各自位数排序时所放进去的数据。

package com.sort;

import java.util.Arrays;

public class RadixSort2 {
    public static void main(String[] args) {
        int[] arr = new int[] {5,7,4,2,0,3,1,6,9,8,11,14,13,155,100,123};
        sort(arr);
        System.out.println(Arrays.toString(arr));
}
    public static void sort(int[] arr) {
        //定义桶
        int[][]bucket = new int[10][arr.length];
        //定义桶记录器
        int[]elementCounts = new int[10];
        //找到数组中的最大值
        int max=arr[0];
        for(int i=0;i<arr.length;i++) {
            if(arr[i]>max) {
                max=arr[i];
            }
        }
        //找到最大值的位数
        int maxLength=(max+"").length();
        int n=1;    
        for(int h=0;h<maxLength;h++) {
            for(int i=0;i<arr.length;i++) {
            int element=arr[i]/n%10;
            int count =elementCounts[element];
            bucket[element][count]=arr[i];
            elementCounts[element]=elementCounts[element]+1;
        }
        int index=0;
        for(int k=0;k<elementCounts.length;k++) {
            if(elementCounts[k]!=0) {
                for(int l=0;l<elementCounts[k];l++) {
                    arr[index] = bucket[k][l];
                    index++;
            }
        }
        elementCounts[k]=0;    
                }
        n=n*10;
            }
     }
}
        
        
        

基数排序2

package com.sort;

import java.util.Arrays;

public class RadixSort {
    public static void main(String[] args) {
        int[] arr = new int[] {5,7,4,2,0,3,1,6,9,8,11,14,13,155,100,123};
        sort(arr);
        System.out.println(Arrays.toString(arr));

    }

    public static void sort(int[] arr) {
        //定义桶
        int[][]bucket = new int[10][arr.length];
        //定义桶记录器
        int[]elementCounts = new int[10];
        //向桶内放数据
        
        for(int i=0;i<arr.length;i++) {
            
            int element = arr[i]/1%10;
            int count=elementCounts[element];
            bucket[element][count]=arr[i];
            elementCounts[element]=elementCounts[element]+1;    
            
    }
        int index=0;
        //将桶内的数据取出
        for(int k=0;k<elementCounts.length;k++) {
            if(elementCounts[k]!=0) {
                for(int l=0;l<elementCounts[k];l++) {
                    arr[index] = bucket[k][l];
                    index++;
                }
            }
            elementCounts[k]=0;
        }
        
        for(int i=0;i<arr.length;i++) {
            int element = arr[i]/10%10;
            int count=elementCounts[element];
            bucket[element][count]=arr[i];
            elementCounts[element]=elementCounts[element]+1;    
        
        
    }
        int index2=0;
        //将桶内的数据取出
        for(int k =0;k<elementCounts.length;k++) {
            if(elementCounts[k]!=0) {
                for(int l=0;l<elementCounts[k];l++) {
                    arr[index2] = bucket[k][l];
                    index2++;
            
            }
        }
            elementCounts[k]=0;    
    }
        
for(int i=0;i<arr.length;i++) {
            
            int element = arr[i] / 100%10;
            int count=elementCounts[element];
            bucket[element][count]=arr[i];
            elementCounts[element]=elementCounts[element]+1;        
    }
        int index3=0;
        //将桶内的数据取出
        for(int k =0;k<elementCounts.length;k++) {
            if(elementCounts[k]!=0) {
                for(int l=0;l<elementCounts[k];l++) {
                    arr[index3] = bucket[k][l];
                    index3++;
            }
        }
            elementCounts[k]=0;    
      }
    }
}


 希尔排序(1)

将小的数据放到前边,大的数据放到后边。通过步长对数据进行分组,将步长设为数组长度的1/2,每次都能将每组在组内进行排序,小数值在前,大数值在后,然后通过改变步长,不断将步长变为上一次步长的1/2,不断调整排序,完成将整个数据排序的操作。

package com.sort;
import java.util.Arrays;


public class ShellSort {
    public static void main(String[] args) {
        int[] arr = new int[] {5,7,4,2,0,3,1,6,9,8,11,14,13,15,10,12};
        sort(arr);
        System.out.println(Arrays.toString(arr));
}
    
    public static void sort(int[] arr) {
        
        //第一轮
        for(int i = 8;i<arr.length;i++) {
            for(int j = i-8;j>=0;j-=8) {
                if(arr[j] > arr[j+8]) {
                    int temp = arr[j];
                    arr[j] = arr[j+8];
                    arr[j+8] = temp;
                }
            }
        }
        //第二轮
        for(int i=4;i<arr.length;i++) {
            for(int j=i-4;j>=0;j-=4) {
                if(arr[j]>arr[j+4]) {
                int temp =arr[j];    
                arr[j]=arr[j+4];
                arr[j+4]=temp;
                    
                }
            }
        }
        
        //第三轮
                for(int i = 2;i<arr.length;i++) {
                    for(int j = i-2;j>=0;j-=2) {
                        if(arr[j] > arr[j+2]) {
                            int temp = arr[j];
                            arr[j] = arr[j+2];
                            arr[j+2] = temp;
                        }
                    }
                }
                
                //第四轮
                for(int i = 1;i<arr.length;i++) {
                    for(int j = i-1;j>=0;j--) {
                        if(arr[j] > arr[j+1]) {
                            int temp = arr[j];
                            arr[j] = arr[j+1];
                            arr[j+1] = temp;
                        }else {
                            break;
                        }
                    }
                }
                
            }
        }
  希尔排序(2)


package com.sort;

import java.util.Arrays;

public class ShellSort2 {
    public static void main(String[] args) {
        int[] arr = new int[] {5,7,4,2,0,3,1,6};
        ShellSort(arr); 
        System.out.println(Arrays.toString(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;j-=gap) {
                    if(arr[j] > arr[j+gap]) {
                        int temp = arr[j];
                        arr[j] = arr[j+gap];
                        arr[j+gap] = temp;
                    }
                }
            }
        }
    }
}
 

  

   

堆排序


大顶堆:在完全二叉树的基础之上,每个节点的值都大于等于其左右孩子的值
小顶堆:在完全二叉树的基础之上,每个节点的值都小于等于其左右孩子的值
注:只看父子关系,不看兄弟关系
第一步:完全二叉树——>大顶堆;
第二步:堆顶元素和堆底元素进行互换;交换完成之后,堆底元素不再参与构建(有序);
第三步:继续构建大顶堆,堆顶和堆底互换;
 

完全二叉树构建大顶堆:
(1)定义一个parent游标和一个child游标;parent游标从后向前移动,如果当前节点没有子树则直接跳过
(2)如果当前节点有子树,先让child执行其左子树
(3)判断该节点有没有右子树,如果有,Child游标指向右子树当前最大的值
(4)当前节点和Child节点的值进行对比,如果当前节点大于child节点的值,parent游标继续向前移动
(5)如果当前节点小于child节点的值,父子节点的值进行交换
(5.1)parent游标指向child游标的位置,child游标的地址=2*child+1
(5.1.1)如果child游标指向空,parent游标继续向前移动
(5.1.2)如果child游标指向不为空,重复第4、5步

package com.sort;

import java.util.Arrays;

public class DuiSort {
    public static void main(String[]args) {
        int[]arr=new int[] {1,2,3,100,23,46,12,34};
        for(int p=arr.length-1;p>=0;p--) {
            sort(arr,p);
            System.out.println(Arrays.toString(arr));
        }}
public static void sort(int[] arr,int parent) {
    //定义左子树
    int child = 2*parent +1;
    while(child<arr.length-1) {
        //排序
        //判断有没有右子树,以及计较左右子树谁大,child指针只想大的
        int rchild = child +1;
        if(rchild<=arr.length-1 && arr[rchild]>arr[child]) {
            child++;
        }
        //父子节点进行对比交换
        if(arr[parent]<arr[child]) {
            //交换
            int temp=arr[parent];
            arr[parent] = arr[child];
            arr[child] = temp;
            
            parent = child;
            child=2* child+1;
            }else {
                break;
            }
        }
}

}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值