Java语言基础day11(五种排序:冒泡排序,选择排序,直接插入排序,希尔排序,快速排序,和二分查找)

本文深入讲解了五种经典的排序算法:冒泡排序、选择排序、直接插入排序、希尔排序和快速排序,每种算法都附有详细的代码实现,帮助读者理解算法原理及应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

冒泡排序

思想:元素两两比较,大的往后放,经过一轮比较后,那么最大的元素就会出现在最后面。

图示:
在这里插入图片描述
代码实现:

import java.util.Arrays;

public class BubbleSortDemo {
    public static void main(String[] args) {
        /*
        *冒泡排序:元素两两比较,大的往后放,经过一轮比较后,那么最大的元素就会出现在最后面。
        * 冒泡排序(从小到大)

        *
        * */
        int[] arr = {24,69,80,57,23};
        Comparison(arr);
        System.out.println(Arrays.toString(arr));

    }
    //crtl+alt+m抽取方法
   public static void Comparison(int[] arr) {
        for (int j = 0; j < arr.length - 1; j++) {//比较的趟数是数组的长度-1;
            for (int i = 0; i < arr.length - 1-j; i++) {//一趟中比较的次数,数组的长度-趟数
                if(arr[i]>arr[i+1]){
                    int temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                }
            }
        }

//        //第一趟,比较了4次
//        for (int i = 0; i < arr.length-1; i++) {
//            if(arr[i]>arr[i+1]){
//                int temp = arr[i];
//                arr[i] = arr[i+1];
//                arr[i+1] = temp;
//            }
//        }
//        //第二趟,比较了3次
//        for (int i = 0; i < arr.length-1-1; i++) {
//            if(arr[i]>arr[i+1]){
//                int temp = arr[i];
//                arr[i] = arr[i+1];
//                arr[i+1] = temp;
//            }
//        }
//        //第三趟,比较了2次
//        for (int i = 0; i < arr.length-1-1-1; i++) {
//            if(arr[i]>arr[i+1]){
//                int temp = arr[i];
//                arr[i] = arr[i+1];
//                arr[i+1] = temp;
//            }
//        }
//      // 第四趟,比较了1次
//        for (int i = 0; i < arr.length-1-1-1; i++) {
//            if(arr[i]>arr[i+1]){
//                int temp = arr[i];
//                arr[i] = arr[i+1];
//                arr[i+1] = temp;
//            }
//        }
    }
}

代码运行结果:

[23, 24, 57, 69, 80]

选择排序

思想:每次拿一个元素,跟他后面的元素,挨个去比,小的往前放,经过一轮比较后,那么最小元素就会放在最前面去。再重复上次。

图示
在这里插入图片描述
代码实现:

import java.util.Arrays;

public class SelectSort {
    public static void main(String[] args) {
        /*选择排序
        *选择排序:每次拿一个元素,跟他后面的元素,
        *挨个去比,小的往前放,经过一轮比较后,那么最小元素就会放在最前面去
        *
        * */
        int[] arr = {24,69,80,57,13};
        tuiDao(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void tuiDao(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 temp = arr[index];
                    arr[index] = arr[i];
                    arr[i] = temp;
                }
            }
        }
//        //第一趟,拿处在第一个元素,与后面的元素一一比较
//        int index = 0;
//        for (int i = 1+index; i < arr.length; i++) {
//            if(arr[0]>arr[i]){
//                int temp = arr[0];
//                arr[0] = arr[i];
//                arr[i] = temp;
//            }
//
//        }
//        //第二趟,拿处在第二个元素,与后面的元素一一比较
//        index = 1;
//        for (int i = 1+index; i < arr.length; i++) {
//            if(arr[1]>arr[i]){
//                int temp = arr[1];
//                arr[1] = arr[i];
//                arr[i] = temp;
//            }
//
//        }
//        //第三趟,拿处在第三个元素,与后面的元素一一比较
//        index = 2;
//        for (int i = 1+index; i < arr.length; i++) {
//            if(arr[2]>arr[i]){
//                int temp = arr[2];
//                arr[2] = arr[i];
//                arr[i] = temp;
//            }
//        }
//        //第四趟,拿处在第四个元素,与后面的元素一一比较
//        index = 2;
//        for (int i = 1+index; i < arr.length; i++) {
//            if(arr[2]>arr[i]){
//                int temp = arr[2];
//                arr[2] = arr[i];
//                arr[i] = temp;
//            }
//        }


    }
}

代码运行结果:

[13, 24, 57, 80, 69]

直接插入排序

算法思路:
直接插入排序,是一种最简单的排序方法.他的基本操作是将一个记录插入到一个长度为m 的有序表中,使之仍保持有序,从而得到一个新的长度为m+1的有序列表.假设有一组元素{k1,k2…,kn},排序开始就认为k1是一个有序序列,让k2插入上述表长为1的有序序列,使之成为一个表长为2的有序序列,然后让k3插入上述表长为2的有序序列,使之成为一个表长为3的有序序列,以此类推,最后让kn插入表长为n-1的有序序列,得到一个表长为n的有序序列。

例如:

	49,38,65,97,76,13,27  原始数据 
	[49],38,65,97,76,13,27 从1索引开始插入 
	[38,49], ,65,97,76,13,27
	[38,49,65] 97,76,13,27
	[38,49,65,97] 76,13,27
	[38,49,65,76,97]13,27
	[13,27,38,49,65,76,97],27
	[13,27,38,49,65,76,97]

代码实现:

import java.util.Arrays;

public class DirectInsertionSort {
    public static void main(String[] args) {
        //直接插入排序:将后面的元素,插入之前的一个有序列表,使之仍然保持有序
        /*一个数组{24,69,80,57};
        * 从第二个数开始,原数组中只有24一个,把第二个数69加入原数组,并与24比较,69大于24则不交换
        * 把第三个数80加入,与原数组(即24,69)依次比较,先与69比较大了不变,再与24比较。
        * 把第四个数57加入,与原数组(即24,69,80)依次比较
        *
        * */

        int[] arr = {24,69,80,57};
        tuiDao(arr);
        System.out.println(Arrays.toString(arr));
    }

    static void tuiDao(int[] arr) {
        for (int j = 1; j < arr.length; j++) {
            //外部循环,b不断的加入新元素
            for (int i = j; i > 0; i--) {
                //里部循环,新加入的数组元素与之前的数组元素依次比较
                if(arr[i]<arr[i-1]){
                    int temp = arr[i];
                    arr[i] = arr[i-1];
                    arr[i-1] = temp;
                }
            }
        }
        
//        for (int j = 1; j < arr.length; j++) {
//            int i =j;
//            while(arr[i]<arr[i-1]&&i>0){
//                int temp = arr[i];
//                arr[i] = arr[i-1];
//                arr[i-1] = temp;
//                i--;
//            }
//        }
       }
}

代码运行结果:

[24, 57, 69, 80]

希尔排序
基本思想:先将原表按增量h(步长)分组,每个子数列按照直接插入法排序,同样。用下一个增量h/2将此数列再分为子数列,直接插入排序。直到h=1时结束。

图示
在这里插入图片描述
代码实现:

import java.util.Arrays;

public class HillSorting {
    public static void main(String[] args) {
        //希尔排序:是对直接插入排序的一种改进,选择一个合适的步长(增量),
        // 然后经过一轮的插入排序让数组大致有序。
        // 不断地缩小步长,进行插入排序,直至步长为一,排序结束
        int[] arr = {7,2,6,9,3};
        shellSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    private static void shellSort(int[] arr) {
        //首次,步长取数组的一半,步长每次缩小取一半
        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]) {
                       swapValue(arr, j, j - h);
                   }
               }
            }
        }

        //克努特序列
        //h=3*h+1
        //来产生,初始值为1。 1,4,13,40,121,364
//        int jianGe = 1;
//        while (jianGe <= arr.length/3){
//            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]) {
//                        swapValue(arr, j, j - h);
//                    }
//                }
//            }
//        }

        
        //定义步长h为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]) {
//                    swapValue(arr, j, j - h);
//                }
//            }
//        }
//        h = 2;//步长为2时
//        for (int i =h; i < arr.length; i++) {
//            for (int j = i; j >h-1;j-=h) {
//                if (arr[j] < arr[j - h]) {
//                    swapValue(arr, j, j - h);
//                }
//            }
//        }
//        h = 1;//步长为1时
//        for (int i =h; i < arr.length; i++) {
//            for (int j = i; j >h-1;j-=h) {
//                if (arr[j] < arr[j - h]) {
//                    swapValue(arr, j, j - h);
//                }
//            }
//        }
    }

    private static void swapValue(int[] arr, int j, int i) {
        int temp = arr[j];
        arr[j] = arr[i];
        arr[i] = temp;
    }
}

运行的结果

[2, 3, 6, 7, 9]

快速排序

实现思路:

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

代码实现:

import java.util.Arrays;

public class Mytest {
    public static void main(String[] args) {
        //快速排序
        int[] arr = {34,23,12,56,45,7,8,97,24,23};
        quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));

    }

    private static void quickSort(int[] arr, int startIndex, int endIndex) {
        if(startIndex < endIndex){
            //找到基准数索引
            int index = getIndex(arr,startIndex,endIndex);
            //对左右两个分区 再进行同样的步骤 ,即是递归调用
            quickSort(arr,startIndex,index);//左半边
            quickSort(arr,index +1,endIndex);//右半边
        }
    }

    private static int getIndex(int[] arr, int startIndex, int endIndex) {
        int i = startIndex;
        int j = endIndex;
        int x = arr[i];
        while(i<j ){
            //由后向前找比他小的数,找到后挖出此数填到前一个坑中。
            while (i<j&&arr[j]>=x){
                j--;
            }
            if(i<j){
                arr[i] = arr[j];
                i++;
            }
            //由前向后找比他大的数,找到后挖出此数填到前一个坑中。
           while (i<j&&arr[i]<x){
                i++;
            }
            if (i < j) {
                arr[j] = arr[i];
                j--; //顺便让j减一下
            }

        }
        //以上循环完毕之后,将基准数填到最后一个坑里面去
        arr[i]=x;
        return i;

    }
}

二分查找

思路:
二分查找是一种非常高效的算法,又称之为折半查找,顾名思义就是将查找的值和数组的中间值作比较【此处就要求这个数组必须是有序的了】

如果被查找的值小于中间值,就在中间值左侧数组继续查找;如果大于中间值,就在中间值右侧数组中查找;否则中间值就是要找的元素。

图示
在这里插入图片描述
代码实现:

public class BinarySearch {
    public static void main(String[] args) {
        //二分查找

        int[] arr = {10,20,30,40,50,60,70,80,90,100};
        int index = findIndex(arr,80);
        System.out.println(index);
        //二分查找的前提是数组有序
        int index1 = selectIndex(arr, 50);
        System.out.println(index1);//4

    }

    private static int selectIndex(int[] arr, int num) {
        int minIndex = 0;
        int endIndex = arr.length-1;
        int centerIndex = (minIndex+endIndex)/2;
        while (minIndex<endIndex){
            if(arr[centerIndex] == num){
                return centerIndex;
            }else if(num<arr[centerIndex]){
                endIndex = centerIndex-1;
            }else if(num>arr[centerIndex]){
                minIndex = centerIndex +1;
            }
            centerIndex = (minIndex+endIndex)/2;
        }
        return -1;

    }

    private static int findIndex(int[] arr, int num) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == num) {
                return i;
            }
        }
        return -1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值