JAVA编写8种排序算法

1.冒泡排序

原理:

数组元素两两比较,交换位置,大元素往后放,那么经过一轮比较后,最大的元素,就会出现在最大索引处

代码

import java.util.Arrays;

public class BubbleSort {
    //冒泡排序
    public static void main(String[] args) {
        //原理:数组元素两两比较,交换位置,大元素往后放,那么经过一轮比较后,最大的元素,就会出现在最大索引处
        int[] arr = {24, 69, 80, 57, 13};

        //分析
         /*
    //第一轮比较
    for (int i = 0; i < arr.length-1; i++) {
            if (arr[i]>arr[i+1]){
                //互换位置
                int t = arr[i];
                arr[i] = arr[i+1];
                arr[i+1]=t;
            }
    }
    //第二轮比较
    for (int i = 0; i < arr.length-1-1; i++) {
            if (arr[i]>arr[i+1]){
                //互换位置
                int t = arr[i];
                arr[i] = arr[i+1];
                arr[i+1]=t;
            }
    }
    //第三轮比较
    for (int i = 0; i < arr.length-1-2; i++) {
            if (arr[i]>arr[i+1]){
                //互换位置
                int t = arr[i];
                arr[i] = arr[i+1];
                arr[i+1]=t;
            }
    }
    //第四轮比较
    for (int i = 0; i < arr.length-1-3; i++) {
            if (arr[i]>arr[i+1]){
                //互换位置
                int t = arr[i];
                arr[i] = arr[i+1];
                arr[i+1]=t;
            }
    }

     */

        int[] result = bubbleSort(arr);
        System.out.println(Arrays.toString(result));

    }
    public static int[] bubbleSort(int[]arr){
        //比较的轮数
        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]){
                    //互换位置
                    int t = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1]=t;
                }

            }
        }
        return arr;




    }


}

2.选择排序

原理:

选择排序原理:从0索引处开始,依次和后面的元素进行比较,小的元素往前放,经过一轮比较后, 最小的元素就出现在了最小索引处

代码

import java.util.Arrays;

public class SelectSort {
    //选择排序
    public static void main(String[] args) {
        //原理:选择排序原理:从0索引处开始,依次和后面的元素进行比较,小的元素往前放,经过一轮比较后, 最小的元素就出现在了最小索引处
        int[] arr = {24, 69, 80, 57, 13, 50};
        //第一轮比较,从0索引开始
        int index = 0;
        
        //分析
        /*第一轮
        for (int i = 1; i < arr.length; i++) {
            if (arr[index]>arr[i]){
                int t = arr[index];
                arr[index] = arr[i];
                arr[i] = t;
            }
        }
        //第二轮
        index = 1;
        for (int i = 1+index; i < arr.length; i++) {
            if (arr[index]>arr[i]){
                int t = arr[index];
                arr[index] = arr[i];
                arr[i] = t;
            }
        }
        //第三轮
        index = 2;
        for (int i = 1+index; i < arr.length; i++) {
            if (arr[index]>arr[i]){
                int t = arr[index];
                arr[index] = arr[i];
                arr[i] = t;
            }
        }
        //第四轮
        index = 3;
        for (int i = 1+index; i < arr.length; i++) {
            if (arr[index]>arr[i]){
                int t = arr[index];
                arr[index] = arr[i];
                arr[i] = t;
            }
        }
        System.out.println(Arrays.toString(arr));
        
         */
        int[] result = selectSort(arr);
        System.out.println(Arrays.toString(result));
    }

    public static int[] selectSort(int[] arr){
        for (int index = 0; index < arr.length-1; index++) {
            for (int i = 1+index; i < arr.length; i++) {
                if (arr[index]>arr[i]){
                    int t = arr[index];
                    arr[index] = arr[i];
                    arr[i] = t;
                }
            }
        }
        return arr;
    }
}

3.直接插入排序

原理

直接插入排序:从1索引处开始,将后面的元素,插入之前的有序列表中使之仍保持有序

代码

import java.util.Arrays;


//直接插入排序
public class DirectInsertionSort {
    public static void main(String[] args) {
        //直接插入排序:从1索引处开始,将后面的元素,插入之前的有序列表中使之仍保持有序
        int[] arr = {24, 69, 80, 57, 13, 50};

        int[] result = directInsertionSort(arr);
        System.out.println(Arrays.toString(result));

    }
    public static int[] directInsertionSort(int[] arr){
        //外层循环定义伦次
//        for (int i = 1; i < arr.length; i++) {
//            //这里循环进行比较插入
//            int j = i;
//            while (j>0 && arr[j]<arr[j-1]){
//                int t = arr[j];
//                arr[j] = arr[j-1];
//                arr[j-1]=t;
//                j--;
//            }
//        }
        for (int i = 1; i < arr.length; i++){
            for (int j =i ; j > 0; j--) {
                if(arr[j]<arr[j-1]){
                    int t = arr[j];
                arr[j] = arr[j-1];
                arr[j-1]=t;
                }
            }
        }
        return arr;
    }
}

4.希尔排序

原理

  1. 希尔排序:他是对插入排序的一个优化,核心的思想就是合理的选取增量,经过一轮排序后, 就会让序列大致有序
  2. 然后再不断的缩小增量,进行插入排序,直到增量为1 那整个排序结束

代码

import java.util.Arrays;

//希尔排序(直接插入排序的的优化)
public class ShillSort {
    public static void main(String[] args) {
        //希尔排序:他是对插入排序的一个优化,核心的思想就是合理的选取增量,经过一轮排序后, 就会让序列大致有序
        //然后再不断的缩小增量,进行插入排序,直到增量为1 那整个排序结束

        int[] arr = {46, 55, 13, 42, 17, 94, 05, 70};
        int[] result = shillSort(arr);
        System.out.println(Arrays.toString(result));
    }

    public static int[] shillSort(int[] arr) {

        /*
        //定义一个增量
        //第一轮增量为4
        int h = 4;
        for (int i = h; i < arr.length; i++){
            for (int j =i ; j > h-1; j-=h) {
                if(arr[j]<arr[j-h]){
                    int t = arr[j];
                    arr[j] = arr[j-h];
                    arr[j-h]=t;
                }
            }
        }
        //第二轮增量为2
        h = 2;
        for (int i = h; i < arr.length; i++){
            for (int j =i ; j > h-1; j-=h) {
                if(arr[j]<arr[j-h]){
                    int t = arr[j];
                    arr[j] = arr[j-h];
                    arr[j-h]=t;
                }
            }
        }
        //第三轮增量为1
        h = 1;
        for (int i = h; i < arr.length; i++){
            for (int j =i ; j > h-1; j-=h) {
                if(arr[j]<arr[j-h]){
                    int t = arr[j];
                    arr[j] = arr[j-h];
                    arr[j-h]=t;
                }
            }
        }*/

//        for (int h = 4; h > 0; h/=2) {
//            for (int i = h; i < arr.length; i++){
//                for (int j =i ; j > h-1; j-=h) {
//                    if(arr[j]<arr[j-h]){
//                        int t = arr[j];
//                        arr[j] = arr[j-h];
//                        arr[j-h]=t;
//                    }
//                }
//            }
//        }
        //希尔排序的思想,合理的选取这个增量
        //第一次这个增量选取数组长度的一半,然后不断的减半

//        for (int h = arr.length/2; h > 0; h/=2) {
//            for (int i = h; i < arr.length; i++){
//                for (int j =i ; j > h-1; j-=h) {
//                    if(arr[j]<arr[j-h]){
//                        int t = arr[j];
//                        arr[j] = arr[j-h];
//                        arr[j-h]=t;
//                    }
//                }
//            }
//        }

        //我们第一 次的增量选择数组长度的一半,还不是很好,我们可以使用一种序列叫做克努特序列
        //克努特序列公式
        //int h=1;
        //h=h*3+1; //1,4,13, 40,121,364
        //根据克努特序列选取我们第一次的增量
        int jiange=1;
        while (jiange<=arr.length/3){
            jiange=jiange*3+1;
        }
        for (int h = jiange; h > 0; h=(h-1)/3) {
            for (int i = h; i < arr.length; i++){
                for (int j =i ; j > h-1; j-=h) {
                    if(arr[j]<arr[j-h]){
                        int t = arr[j];
                        arr[j] = arr[j-h];
                        arr[j-h]=t;
                    }
                }
            }
        }

        return arr;

    }
}

5.快速排序

原理

  1. 将基准数挖出形成第一个坑。
  2. 由后向前找比他小的数,找到后挖出此数填到前一个坑中。
  3. 由前向后找比他大或等于的数,找到后也挖出此數填到前一个坑中。
  4. 再重复执行2,3两步骤,

代码

import java.util.Arrays;

//快速排序
public class QuickSort {
    public static void main(String[] args) {
        //定义了一个数组
        int[] arr = {10, 3, 5, 6, 1, 0, 100, 40, 50, 8};
        //调用工具类,进行快速排序传入数组,传入起始位置,传入结束位置
        QuickSortUtils.quickSort(arr,0,arr.length-1);
        //输出排序后的结果
        System.out.println(Arrays.toString(arr));
    }
}
class QuickSortUtils {
    //快速排序
    public static void quickSort(int[] arr,int start, int end){
        //找出分左右两区的的索引位置,然后对左右两区进行递归调用
        if (start<end){
            int index = getIndex(arr,start,end);
            quickSort(arr,start,index-1);
            quickSort(arr,index+1,end);
        }
    }
    //将基准数挖出形成第一个坑。
    //由后向前找比他小的数,找到后挖出此数填到前一个坑中。
    //由前向后找比他大或等于的数,找到后也挖出此數填到前一个坑中。
    //再重复执行2,3两步骤,

    private static int getIndex(int[] arr, int start, int end) {
        int i = start;
        int j = end;
        int x = arr[i];
        while (i<j){

            //由后向前找比他小的数,找到后挖出此数填到前一个坑中。
            while (i<j &&arr[j]>=x){//需要找比arr[i]小的数,如果比他大,则角标-1接着找
                j--;
            }
            if (i<j){
                arr[i] = arr[j];
                i++;
            }

            //由前向后找比他大或等于的数,找到后也挖出此數填到前一个坑中。
            while (i<j &&arr[i]<x){//需要找比arr[i]小的数,如果比他大,则角标-1接着找
                i++;
            }
            if (i<j){
                arr[j] = arr[i];
                j--;
            }
        }
        //把基准位填入到最后的坑位
        arr[i] = x;

        return i;
    }
}

6.归并排序

原理

拆分-归并

代码

import java.util.Arrays;

//归并排序
public class MergeSort {
    public static void main(String[] args) {
        //我们先给一个左右两边是有序的一个数组,先来进行归并操作.
        int[ ] arr={4,5,7,8,        1,2,3,6};
        //拆分
        chaifen(arr,0,arr.length-1);

        //归并
        mergeSort(arr,0,(arr.length-1)/2,arr.length-1);

        //输出原数组
        System.out.println(Arrays.toString(arr));
    }

    private static void chaifen(int[] arr, int startIndex, int endIndex) {
        //计算中间索引
        int centerIndex = (startIndex+endIndex)/2;
        if (startIndex<endIndex){
            //拆成单个的
            chaifen(arr,startIndex,centerIndex);
            chaifen(arr,centerIndex+1,endIndex);
//            开始归并排序
            mergeSort(arr,startIndex,centerIndex,endIndex);
        }
    }

    private static void mergeSort(int[] arr, int startIndex, int centerIndex, int endIndex) {
        //定义一个临时数组
        int[] tempArr = new int[endIndex-startIndex+1];
        //定义左边数组起始索引
        int i= startIndex;
        //定义右边数组起始索引
        int j = centerIndex+1;
        //定义临时数组起始索引
        int index = 0;
        //比较左右两个数组的元素大小,往临时数组中放
        while (i<=centerIndex && j<=endIndex){
            if (arr[i]<=arr[j]){
                tempArr[index] = arr[i];
                i++;
            }else {
                tempArr[index] = arr[j];
                j++;
            }
            index++;
        }

        //假如不能对半分完,应该处理剩余元素
        //处理剩余元素
        while (i<=centerIndex){
            tempArr[index] = arr[i];
            i++;
            index++;
        }
        //处理剩余元素
        while (j<=endIndex){
            tempArr[index] = arr[j];
            j++;
            index++;
        }
        //System.out.println(Arrays.toString(tempArr));
        //将临时数组中的元素取到原数组中
        for (int k = 0; k < tempArr.length; k++) {
            arr[k+startIndex] = tempArr[k];
        }

    }
}

7.基数排序

原理

基数排序:通过分配再收集的方式进行排序

import java.util.Arrays;

//基数排序
public class BaseOrder {
    public static void main(String[] args) {
        // 基数排序:通过分配再收集的方式进行排序
        int[] arr = {2,1,5,21, 31, 444, 23, 33, 47, 10, 903, 124, 987,100};
        //得确定排序轮次,
        //获取数组中的最大值
        //int max=getMax(arr) ;

        //基数排序
        baseOrder(arr);
        //输出基数排序的结果
        System.out.println(Arrays.toString(arr));


    }

    private static void baseOrder(int[] arr) {
        //定义二维数组,放10个桶,每个桶最大容量为数组的最大值
        int[][] tempArr = new int[10][arr.length];
        //定义统计数组
        int[] counts = new int[10];

        int max = getMax(arr);
        int len = String.valueOf(max).length();//排序几轮
        //循环轮次
        for (int i = 0,n=1; i < len; i++,n*=10) {
            for (int j = 0; j < arr.length; j++) {
                //获取每个位上的数字
                int ys = arr[j]/n%10;
                tempArr[ys][counts[ys]++] = arr[j];
            }
            //取出桶中的元素
            int index = 0;
            for (int k = 0; k < counts.length; k++) {
                if (counts[k]!=0){
                    for (int h = 0; h < counts[k]; h++) {
                        //从桶中取出元素放回原数组
                        arr[index] = tempArr[k][h];
                        index++;
                    }
                    counts[k]=0;//清除上一次统计的个数
                }
            }
        }
    }

    private static int getMax(int[] arr) {
        int max = arr[0];
        for (int i = 1;i<arr.length;i++){
            if (arr[i]>max){
                max=arr[i];
            }
        }
        return max;
    }
}

8.堆排序

原理

先把数组变成一个大顶堆,然后把根元素和最后一个元素进行调换,再进行顶堆操作

代码

import java.util.Arrays;

//堆排序
public class HeapSort {
    public static void main(String[] args) {
        //定义一个数组
        int[] arr={1,0,6,7,2,3,4};
        //调整成大顶堆的方法
        //定义开始调整的位置
        int startIndex = (arr.length-1)/2;
        //循环开始调
        for (int i = startIndex; i >= 0; i--) {
            toMaxHeap(arr,arr.length,i);
        }
        //System.out.println(Arrays.toString(arr));
        //经过上面的操作后,已经把数组变成一个大顶堆,把根元素和最后一个元素进行调换
        for (int i = arr.length-1; i >0; i--) {
            //进行调换
            int t = arr[0];
            arr[0] = arr[i];
            arr[i] = t;
            //换完之后,1我们再把剩余元素调成大顶堆
            toMaxHeap(arr,i,0);
        }
        System.out.println(Arrays.toString(arr));
    }

    /**
     *
     * @param arr   要排序的数组
     * @param size  调整的元素个数
     * @param index 从哪里开始调整
     */
    private static void toMaxHeap(int[] arr, int size, int index) {
        //获取左右子节点的索引
        int leftNodeIndex = index*2+1;
        int rightNodeIndex = index*2+2;
        //查找最大节点所对应的索引
        int maxIndex = index;
        if (leftNodeIndex<size && arr[leftNodeIndex]>arr[maxIndex]){
            maxIndex = leftNodeIndex;
        }
        if (rightNodeIndex<size && arr[rightNodeIndex]>arr[maxIndex]){
            maxIndex = rightNodeIndex;
        }
        //我们来调换位置
        if (maxIndex!=index){
            int t=arr[maxIndex];
            arr[ maxIndex]=arr[index];
            arr[index]=t;
            //调换完之后可能会影响到下面的子树不是大顶堆,我们还需要再次调换
            toMaxHeap(arr,size,maxIndex);
        }

    }
}

建议参看视频学习

西部开源Java之数组与排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值