13.Java-数组高级冒泡排序、高级选择排序、直接插入排序、快速排序、基数排序、二分查找

本文详细介绍了Java中几种高级排序算法,包括冒泡排序的原理图解和代码实现,选择排序的原理,直接插入排序的流程,快速排序的方法,基数排序的细节,以及两种不同版本的二分查找技术。通过这些内容,读者可以深入理解各种排序算法的工作机制并掌握其实现方式。
摘要由CSDN通过智能技术生成

13.Java-数组高级冒泡排序、高级选择排序、直接插入排序、快速排序、基数排序、二分查找

一、数组高级冒泡排序原理图解

A:画图演示
	需求:
		数组元素:{24, 69, 80, 57, 13}
		请对数组元素进行排序。
		
B:冒泡排序原理
		相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处

二、数组高级冒泡排序代码实现

package org.westos.java12;
/*A:画图演示
        需求:
        数组元素:{24, 69, 80, 57, 13}
        请对数组元素进行排序。

        B:冒泡排序原理
        相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处*/
public class Test8 {
//从小到大排序
    public static void main(String[] args) {
        int[] arr={24,69,80,57,13};
        for (int i = arr.length-1; i > 0; i--) {
            for (int j = 0; j < i; j++) {
                if(arr[j]>=arr[j+1]){
                    int t=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=t;
                }
            }
        }
        String s="[";
        for (int i = 0; i < arr.length; i++) {
            if(i==arr.length-1){
                s+=arr[i]+"]";
            }else{
                s+=arr[i]+",";
            }
        }
        System.out.println(s);
    }
}
package org.westos.java12;
/*A:画图演示
        需求:
        数组元素:{24, 69, 80, 57, 13}
        请对数组元素进行排序。

        B:冒泡排序原理
        相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处*/
public class Test8 {
//从大到小排序
    public static void main(String[] args) {
        int[] arr={24,69,80,57,13};
        for (int i = arr.length-1; i > 0; i--) {
            for (int j = 0; j < i; j++) {
                if(arr[j]<=arr[j+1]){
                    int t=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=t;
                }
            }
        }
        String s="[";
        for (int i = 0; i < arr.length; i++) {
            if(i==arr.length-1){
                s+=arr[i]+"]";
            }else{
                s+=arr[i]+",";
            }
        }
        System.out.println(s);
    }
}

package org.westos.java12;

import java.util.Arrays;

/*A:画图演示
        需求:
        数组元素:{24, 69, 80, 57, 13}
        请对数组元素进行排序。

        B:冒泡排序原理
        相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处*/
public class Test8 {
    public static void main(String[] args) {
        int[] arr={24,69,80,57,13};
        for (int i = 0; i < arr.length - 1; i++) {
            //不-i也可以算出正确结果,但是在代码的运行效率上,增加了很多不必要的循环比较操作
            for (int j = 0; j < arr.length - 1-i; j++) {
                if(arr[j]>=arr[j+1]){
                    int t=arr[j+1];
                    arr[j+1]=arr[j];
                    arr[j]=t;
                }
            }
        }
        System.out.println(Arrays.toString(arr)); //[13, 24, 57, 69, 80]
    }
}

三、数组高级选择排序原理图解

A:画图演示
	需求:
		数组元素:{24, 69, 80, 57, 13}
		请对数组元素进行排序。
		
B:选择排序原理
		从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处
package org.westos.java15;

import java.util.Arrays;

/*A:画图演示
        需求:
        数组元素:{24, 69, 80, 57, 13}
        请对数组元素进行排序。

        B:选择排序原理
        从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处*/
public class XuZe {
    public static void main(String[] args) {
        int[] arr={24,69,80,80,57,13};
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = i+1; j < arr.length; j++) {
                if(arr[i]>arr[j]){
                    int t=arr[i];
                    arr[i]=arr[j];
                    arr[j]=t;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

四、直接插入排序

package org.westos.java15;
//直接插入排序:从1索引处开始,把后面的每一个元素,插入到之前的一个有序序列,使之仍保持有序。
//   [9]  2,1, 4, 3, 5, 7, 6, 8, 11, 10, 13, 12

//  [2,9] 1, 4, 3, 5, 7, 6, 8, 11, 10, 13, 12
//[1,2,9] 4, 3, 5, 7, 6, 8, 11, 10, 13, 12
//[1,2,4,9] 3, 5, 7, 6, 8, 11, 10, 13, 12

// [1, 2, 3,4, 0] 9,5, 7, 6, 8, 11, 10, 13, 12

import java.util.Arrays;

public class ZhiJieChaRu {
    public static void main(String[] args) {
        int[] arr={9,1,2,8,5,45,45,6,9};
        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;
                }
            }
        }
        System.out.println(Arrays.toString(arr));

    }
}

package org.westos.java15;
//直接插入排序:从1索引处开始,把后面的每一个元素,插入到之前的一个有序序列,使之仍保持有序。
//   [9]  2,1, 4, 3, 5, 7, 6, 8, 11, 10, 13, 12

//  [2,9] 1, 4, 3, 5, 7, 6, 8, 11, 10, 13, 12
//[1,2,9] 4, 3, 5, 7, 6, 8, 11, 10, 13, 12
//[1,2,4,9] 3, 5, 7, 6, 8, 11, 10, 13, 12

import java.util.Arrays;

// [1, 2, 3,4, 0] 9,5, 7, 6, 8, 11, 10, 13, 12
public class ZhiJieChaRu2 {
    public static void main(String[] args) {
        int[] arr={9,1,2,8,5,45,45,6,9};
        for (int i = 1; i < arr.length; i++) {
            int j=i;
            while(j>0&&arr[j]<arr[j-1]){ //循环次数相比上一种要少
                swapValue(arr,j,j-1);
                j--;
            }
        }
        System.out.println(Arrays.toString(arr)); //[1, 2, 5, 6, 8, 9, 9, 45, 45]
    }
    public static void swapValue(int[] arr,int index1,int index2){
        int t=arr[index1];
        arr[index1]=arr[index2];
        arr[index2]=t;
    }
}

五、快速排序

分治法:比大小,再分区
1.从数组中取出一个数,作为基准数。
2.分区:将比这个数大或等于的数全放到他的右边,小于他的数
全放到他的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
挖坑填数
1.将基准数挖出形成第一个坑。
2.由后向前找比他小的数,找到后挖出此数填到前一个坑中。
3.由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中。
4.再重复执行2,3两步骤。
例如对 5391672408 进行排序
package org.westos.java16;

//从小到大快速排序
public class QuickSortTest {
    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);
        }

    }

    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){ //右边放的是比基数大的数
                j--;
            }
            if(i<j){
                arr[i]=arr[j];
                i++;
            }
            while(i<j&&arr[i]<x){ //左边放的是比基数小的数
                i++;
            }
            if(i<j){
                arr[j]=arr[i];
                j--;
            }
        }
        arr[i]=x;
        return i;
    }
}
package org.westos.java16;

//从大到小快速排序
public class QuickSortTest {
    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);
        }

    }

    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){  //右边放的是比基数小的数
                j--;
            }
            if(i<j){
                arr[i]=arr[j];
                i++;
            }
            while(i<j&&arr[i]>=x){ //左边放的是比基数大的数
                i++;
            }
            if(i<j){
                arr[j]=arr[i];
                j--;
            }
        }
        arr[i]=x;
        return i;
    }
}
package org.westos.java16;

import java.util.Arrays;

public class Test9 {
    public static void main(String[] args) {
        int[] arr={1,20,5,1,4,8,9,20,2,50,9};
        QuickSortTest.quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
}

六、基数排序

基数排序不同于之前所介绍的各类排序
前边介绍到的排序方法或多或少的是通过使用比较和移动记录来实现排序
而基数排序的实现不需要进行对关键字的比较
只需要对关键字进行“分配”与“收集”两种操作即可完成。
package org.westos.java16;

import java.util.Arrays;
//从小到大基数排序
public class Test10 {
    public static void main(String[] args) {
        int[] arr={1,25,5,89,6,54,21,3,2,0};
        sortArr(arr);
        System.out.println(Arrays.toString(arr)); //[0, 1, 2, 3, 5, 6, 21, 25, 54, 89]

    }

    private static void sortArr(int[] arr) {
        int[][] sum=new int[10][arr.length];
        int[] counts=new int[10];
        int max=getmax(arr);
        int length = String.valueOf(max).length();
        for (int i = 0,n=1; i < length; i++,n*=10) {
            for (int j = 0; j < arr.length; j++) {
                int ys=arr[j]/n%10;
                sum[ys][counts[ys]++]=arr[j];
            }
            int index=0;
            for (int k = 0; k < counts.length; k++) {
                if(counts[k]!=0){
                    for (int u = 0; u < counts[k]; u++) {
                        arr[index]=sum[k][u];
                        index++;
                    }
                    counts[k]=0;
                }
            }
        }
    }

    private static int getmax(int[] arr) {
        int max=arr[0];
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]>max){
                max=arr[i];
            }
        }
        return max;
    }
}
package org.westos.java16;

import java.util.Arrays;
//从大到小基数排序
public class Test10 {
    public static void main(String[] args) {
        int[] arr={1,25,5,89,6,54,21,3,2,0};
        sortArr(arr);
        System.out.println(Arrays.toString(arr)); //[89, 54, 25, 21, 6, 5, 3, 2, 1, 0]

    }

    private static void sortArr(int[] arr) {
        int[][] sum=new int[10][arr.length];
        int[] counts=new int[10];
        int max=getmax(arr);
        int length = String.valueOf(max).length();
        for (int i = 0,n=1; i < length; i++,n*=10) {
            for (int j = 0; j < arr.length; j++) {
                int ys=arr[j]/n%10;
                sum[ys][counts[ys]++]=arr[j];
            }
            if(i==length-1){
                int index=arr.length-1;
                for (int k = 0; k < counts.length; k++) {
                    if(counts[k]!=0){
                        for (int u = 0; u < counts[k]; u++) {
                            arr[index]=sum[k][u];
                            index--;
                        }
                        counts[k]=0;
                    }
                }
                break;
            }
            int index=0;
            for (int k = 0; k < counts.length; k++) {
                if(counts[k]!=0){
                    for (int u = 0; u < counts[k]; u++) {
                        arr[index]=sum[k][u];
                        index++;
                    }
                    counts[k]=0;
                }
            }
        }
    }

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

七、二分查找

A:画图演示
B:二分查找:前提数组元素必须有序   
C:二分查找的思想:每一次都查中间索引的那个元素,比较大小就能减少一半的元素。

 注意:二分查找不是找该元素第一次出现的索引。
 比如下面这个数组,找4元素的索引,找出来的索引是5
 int[] arr = {1,2,3,4,4,4,6,7,8,9,10};
 
基本查询:从头开始挨个往后找,该元素第一次出现的索引。
package org.westos.java16;

import java.util.Arrays;

/*A:画图演示
        B:二分查找:前提数组元素必须有序
        C:二分查找的思想:每一次都查中间索引的那个元素,比较大小就能减少一半的元素。

        注意:二分查找不是找该元素第一次出现的索引。
        比如下面这个数组,找4元素的索引,找出来的索引是5
        int[] arr = {1,2,3,4,4,4,6,7,8,9,10};


        基本查询:从头开始挨个往后找,该元素第一次出现的索引。*/
public class Test11 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,4,4,6,7,8,9,10};
/*      基本查询
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]==4){
                System.out.println(i);
                break;
            }
        }*/
        System.out.println(sortBinary(arr, 10)); //10
        System.out.println(sortBinary(arr, 4)); //5 不是第一次出现4的索引值
        System.out.println(Arrays.binarySearch(arr, 8)); //8
        int i = binarySearch0(arr, 0, arr.length, 7);
        System.out.println(i); //7


    }
    public static int sortBinary(int[] arr,int num){
        int start=0;
        int end=arr.length-1;
        while(start<=end){
            int mid=(start+end)/2;
            if(arr[mid]==num){
                return mid;
            }else if(arr[mid]>num){
                end=mid-1;
            }else{
                start=mid+1;
            }
        }
        return -1;

    }
    private static int binarySearch0(int[] a, int fromIndex, int toIndex,
                                     int key) {
        int low = fromIndex;
        int high = toIndex - 1;

        while (low <= high) {
            //移位运算符的效率比较高,是对补码进行操作的,右移一位即除以2
            int mid = (low + high) >>> 1; 
            int midVal = a[mid];

            if (midVal < key)
                low = mid + 1;
            else if (midVal > key)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found.
    }
}

八、改进版二分查找

package org.westos.java16;

import java.util.Arrays;

//二分查找从小到大排序
public class Test29 {
    public static void main(String[] args) {
        int[] arr={1,2,2,2,6,7,8,9};
/*        int[] arr2={4,4,4,4,4};*/
        int i = Arrays.binarySearch(arr, 2); //3 不一定是第一个出现元素的索引值
        System.out.println(i);
        System.out.println(searchBinary(arr, 2)); //1 改进版能够找到第一个元素出现的索引值


    }
    public static int searchBinary(int[] arr,int num){
        int start=0;
        int end=arr.length-1;
        while(start<=end){
            int mid=(start+end)>>1;
            if(arr[mid]>num){
                end=mid-1;
            }else if(arr[mid]<num){
                start=mid+1;
            }else{
                while(mid>0&&arr[mid-1]==arr[mid]){
                    mid--;
                }
                return mid;
            }
        }
        return -(start+1);
    }
}
package org.westos.java16;

//二分查找从大到小排序
public class Test31 {
    public static void main(String[] args) {
        int[] arr={9,8,8,8,6,5,5,5,4,3,2};
/*                int[] arr2={4,4,4,4,4};*/
        System.out.println(searchBinary2(arr, 5)); //5 改进版能够找到第一个元素出现的索引值


    }
    public static int searchBinary2(int[] arr,int num){
        int start=0;
        int end=arr.length-1;
        while(start<=end){
            int mid=(start+end)>>1;
            if(arr[mid]>num){
                start=mid+1;
            }else if(arr[mid]<num){
                end=mid-1;
            }else{
                while(mid>0&&arr[mid-1]==arr[mid]){
                    mid--;
                }
                return mid;
            }
        }
        return -(start+1);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值