Java数组与八大排序

文章目录

  • 浅谈数组
    • 数组初始化
    • 知识捡漏静态初始化写法
    • 数组操作:反转
    • 二维数组
    • 数组的练习:根据数组元素查找该元素第一次在数组中出现的索引
      • 方法1:挨个遍历查找法
      • 方法2:二分查找法
  • 二 数组常见的八大排序方法
    • 2.1 冒泡排序
      • 图解
      • 举个栗子
    • 2.2 选择排序
      • 图解
    • 举个栗子
    • 2.3 插入排序
    • 2.4 希尔排序【基于插入排序,大大提高插入排序的执行效率】
      • 正常序列
      • 伯努利序列
    • 2.5 快速排序
      • 原理
      • 实现思路
    • 2.6 归并排序
    • 2.7 基数排序
    • 2.7 堆排序

浅谈数组

  • 数组的出现,是为了我们方便的去操作多个数据
  • 数组,相当于一个容器,可以存储一组,相同数据类型的元素
  • 数组既可以存储基本数据类型,也可以存储引用数据类型
  • 数组的定义格式
int[] arr=new int[10];
double arr2[]=new double[10];

Java数组与八大排序_第1张图片

数组初始化

  • Java中的数组必须先初始化然后才能使用
  • 所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值
  • 初始化的分类:
    • a:动态初始化:只指定长度,由系统给出初始化值
    • b:静态初始化:给出初始化值,由系统决定长度
    • 注意事项:这两种方式,只能使用一种,不能进行动静结合
      动态初始化的格式:
    • 数据类型[] 数组名=new数据类型[数组长度]
    • 数组长度其实就是数组中元素的个数。
      举例:int[] arr=new int[3];定义了一个int类型的数组arr,这个数组可以存放3个int的值。

知识捡漏静态初始化写法

int[] arr=new int[]{10,20,30,40};
//简写方法
double[] arr={3.1425648};

数组操作:反转

    public static void main(String[] args) {
    int[] arr={10,80,50,4,5,6};
    for(int i=0;i<arr.length/2;i++) {
        int temp=arr[i];
        arr[i]=arr[arr.length-1-i];
        arr[arr.length-1-i]=temp;
    }
        System.out.println(Arrays.toString(arr));

    }

在这里插入图片描述

二维数组

数据类型[][] 变量名= new 数据类型[m][n];
m:二维数组有多少个一维数组
n:每个一维数组的元素个数
其他格式;
	a:数据类型 数组名[][]=new 数据类型[m][n];
	b:数据类型 数组名[][]=new 数据类型[m][n];
 public static void main(String[] args) {
        int[][] arr=new int[3][4];
        System.out.println(arr);//输出二维数组的地址
        System.out.println(arr[0]);//输出一维数组的地址
        System.out.println(arr[1]);
        //给二维数组里面的每个元素
        int[][] arr2=new int[][]{{20,62,4},{80,30,95},{10,101}};
        //输出最后一个元素的索引=数组的长度-1
        System.out.println(arr[arr.length-1][arr[arr.length-1].length-1]);
    }

Java数组与八大排序_第2张图片

数组的练习:根据数组元素查找该元素第一次在数组中出现的索引

方法1:挨个遍历查找法

public static void main(String[] args) {
        int[] array={10,15,78,96,45,2,16};
        int index=getIndexByEle(array,2);
        System.out.println(index);
    }

    private static int getIndexByEle(int[] array,int ele) {
        for(int i=0;i< array.length;i++) {
            if(ele==array[i]) {
                return i;
            }
        }
        //没有找到返回-1
        return -1;
    }

Java数组与八大排序_第3张图片

方法2:二分查找法

  • 使用二分查找的条件:
    • 该数组的元素必须有序
  • 二分查找的思想:
    • 每一次查找中间的元素,比较大小就能减少一半的元素
      Java数组与八大排序_第4张图片
package 数组;

import java.util.Scanner;

public class 二分查找 {
    public static void main(String[] args) {
        //二分查找,数组必须有顺序,否则,使用普通查找
        int[] array={10,20,30,40,50,60,70,80,90};

        System.out.println("请输入你要查找的数字【10~100的整十的整数】:");
        Scanner scanner=new Scanner(System.in);
        int ele= scanner.nextInt();
        scanner.close();
        int index=getIndexByEle(array,ele);

        if(index==-1) {
            System.out.println("不好意思,没有这个元素");
        }
        else {
            System.out.println("元素的索引为:"+index);
        }
    }

    private static int getIndexByEle(int[] array, int ele) {

        int minIndex=0;
        int maxIndex= array.length-1;
        int centerIndex=(minIndex+maxIndex)/2;
        while (minIndex<=array[maxIndex]) {
            if(ele==array[centerIndex]) {
                return centerIndex;
            }
            else if(ele<array[centerIndex]) {
                maxIndex= centerIndex-1;
            }
            else if(ele>array[centerIndex]) {
                minIndex=centerIndex+1;
            }
            //需重新计算centerIndex的值
            centerIndex=(minIndex+maxIndex)/2;
        }

        //找不到返回-1
        return -1;
    }
}

Java数组与八大排序_第5张图片

二 数组常见的八大排序方法

2.1 冒泡排序

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

图解

Java数组与八大排序_第6张图片

举个栗子

package 数组;

import java.util.Arrays;
//冒泡排序
public class BubbleSort {
    public static void main(String[] args) {
        int[] array={1,15,14,88,99,75,65,999};
        for(int i=1;i<array.length;i++) {
            boolean flag=false;
            for(int j=0;j<array.length-i;j++) {
                if(array[j]>array[j+1]) {
                    int temp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=temp;
                    flag=true;
                }
                if(!flag) {
                    continue;
                }
            }
        }
        System.out.print(Arrays.toString(array));
        /*for(int i:array) {
            System.out.print(i+"\t");
        }*/
    }
}

在这里插入图片描述

2.2 选择排序

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

图解

Java数组与八大排序_第7张图片

举个栗子

package 数组;

import java.util.Arrays;
//选择排序
public class SelectSort {
    public static void main(String[] args) {
        //选择排序原理:从0索引处开始,依次和后面的元素进行比较,
        // 小的元素往前放,经过一轮比较后,最小的元素就出现在了最小索引处
        int[] arr={66,88,55,77,99,11};
        for (int index = 0; index < arr.length; index++) {
            for (int i = index+1; i < arr.length; i++) {
                if(arr[index]>arr[i]) {
                    int temp=arr[index];
                    arr[index]=arr[i];
                    arr[i]=temp;
                }
            }
        }

        System.out.println(Arrays.toString(arr));
    }
}

Java数组与八大排序_第8张图片

2.3 插入排序

  • 排序原理:算法思路:直接插入排序,是一种最简单的排序方法.他的基本操作是将一个记录插入
    到一个长度为m的有序表中使之仍保持有序
    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]
package 数组;

import java.util.Arrays;
//插入排序
public class InsertSort {
    public static void main(String[] args) {
        int[] arr={14,89,23,45,87,12,56};
        for (int i = 1; i < arr.length; i++) {
            for(int j=i;j>0;j--) {
                if(arr[j-1]>arr[j]) {
                    int temp=arr[j-1];
                    arr[j-1]=arr[j];
                    arr[j]=temp;
                }
            }
        }

        System.out.println(Arrays.toString(arr));
    }
}

Java数组与八大排序_第9张图片

2.4 希尔排序【基于插入排序,大大提高插入排序的执行效率】

  • 希尔排序又称缩小增量排序。
    • 基本思想:先将原表按增量ht分组,每个子文件按照直接插入法排序。同样,用下一个增量ht/2将文件再分为子文件,再直接插入法排序。直到ht-1时整个文件排好序。
    • 关键:选择合适的增量。
    • 希尔排序算法9-3:可以通过三重循环来实现。
    1. 希尔排序的核心思想:是选取合理的选取增量,经过一轮排序后,就会让排序大致有序
    1. 然后再不断的缩小增量,进行插入排序,直到增量为1
    1. 直接插入排序,其实就是增量为1的希尔排序
      Java数组与八大排序_第10张图片
  • 增量的合理选择:最普通的选择就是使用数组长度的一半,这种增量从效率来说不是很好。

正常序列

package 数组;

import java.util.Arrays;
//希尔排序
public class ShellsSort {
    public static void main(String[] args) {
        //希尔排序思想--快速排序的优化,合理的选取这个增量
        //第一次这个增量选取数组长度的一半,然后不断减半
        int[] arr={78,56,12,23,88,50,64,25,78,40,63};
        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);
                    }
                }
            }
        }

        System.out.println(Arrays.toString(arr));
    }
    public static void swapValue(int[] arr,int i,int j) {
        int temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }
}

Java数组与八大排序_第11张图片

伯努利序列

package 数组;
//希尔排序
public class ShellSort2 {
    public static void main(String[] args) {
        //克努特序列
        //h=1
        //h=h*3+1 1,4,13,40,121,364
        int[] arr={78,56,12,23,88,50,64,25,78,40,63};
        int interval=1;
        while(interval<=arr.length/3) {
            interval=interval*3+1;
        }

        for(int h=interval;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);
                    }
                }
            }
        }

        for(int x:arr) {
            System.out.print(x+"\t");
        }
    }

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

Java数组与八大排序_第12张图片

2.5 快速排序

原理

  • 分治法:比大小,再分区
    • 1.从数组中取出一个数,作为基准数
    • 2.分区:将比这个数大或等于的数全放到他的右边,小于他的数全放到他的左边
    • 3.再对左右区间重复第二步,直到各区间只有一个数

实现思路

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

import java.util.Arrays;
//快速排序 挖坑填数
public class QuickSort {
    public static void main(String[] args) {
        //定义一个数组
        int[] arr={13,15,78,-1,22,21,100,56,36,46,98};

        //调用方法,进行快速排序,传入数组,传入起始位置,传入结束位置
        Quicksort(arr,0,arr.length-1);

        System.out.println(Arrays.toString(arr));
    }

    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) {
                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;
    }
}

Java数组与八大排序_第13张图片

2.6 归并排序

  • 归并排序(MergeSort)就是利用归并的思想实现排序的方法。
  • 它的原理是假设初始序列有N个记录,则可以看成是N个有序的子序列,每个子序列的长度为1,然后两两归并,得到N/2个长度为2或1的有序子序列,再两两归并…如此重复,直至得到一个长度为N的有序序列为止,这种排序方法称为2路归并排序。

Java数组与八大排序_第14张图片

package 数组;

import java.util.Arrays;

//归并排序
public class MergeSort {
    public static void main(String[] args) {
        int[] arr={10,20,8,2,-20,-15,55,99,30};

        //拆分
        split(arr,0, arr.length-1);
        //归并
        merge(arr,1,arr.length/2,arr.length-1);
        //输出数组
        System.out.println(Arrays.toString(arr));
    }

    private static void split(int[] arr, int startIndex, int endIndex) {
        //计算中间数组
        int centerIndex=(startIndex+endIndex)/2;
        if(startIndex<endIndex) {
            split(arr,startIndex,centerIndex);
            split(arr,centerIndex+1,endIndex);
            merge(arr,startIndex,centerIndex,endIndex);
        }
    }

    private static void merge(int[] arr, int startIndex, int centerIndex, int endIndex) {
        //定义一个临时数组
        int[] tempArr=new int[endIndex-startIndex+1];
        //定义左边数组的起始索引
        int i=startIndex;
        //定义右边数组的起始索引
        int j=centerIndex;
        //定义临时变量数组的起始索引
        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++;
        }

        //将临时数组的值取到原数组
        if (tempArr.length >= 0) System.arraycopy(tempArr, 0, arr,  startIndex, tempArr.length);
    }
}

Java数组与八大排序_第15张图片

2.7 基数排序

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

import java.util.Arrays;
//温馨提示:此排序方法不可以对负数进行排序
//基数排序:通过分配再收集的方式进行排序
public class RadixSort {
    public static void main(String[] args) {
        int[] arr={1,5,21,32,444,545,124,903,9999};
        //确定排序轮次

        //基数排序
        sortArray(arr);
        //输出排序后的数组
        System.out.println(Arrays.toString(arr));
    }

    private static void sortArray(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:arr) {
                //获取每个位上的数字
                int bitValue=j/n%10;
                tempArr[bitValue][counts[bitValue]++]=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 temp=arr[0];
        for(int x:arr) {
            if(temp<x) {
                temp=x;
            }
        }
        return temp;
    }
}

Java数组与八大排序_第16张图片

2.7 堆排序

堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序

  • 堆排序的基本思想是
      1. 将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点
      1. 将其与未尾元素进行交换,此时末尾就为最大值
      1. 然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值
      1. 如此反复执行,便能得到一个有序序列了

Java数组与八大排序_第17张图片
Java数组与八大排序_第18张图片
Java数组与八大排序_第19张图片

package 数组;

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);
        }

        //经过上面的操作后,已经把数组变成一个大顶堆,把根元素和最后一个元素进行调换
        for(int i=arr.length-1;i>0;i--) {
            int temp=arr[0];
            arr[0]=arr[i];
            arr[i]=temp;
            //换完之后,再把剩余的元素调成大队堆
            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;
        //leftNodeIndex
        if(leftNodeIndex<size && arr[leftNodeIndex]>arr[maxIndex]) {
            maxIndex=leftNodeIndex;
        }
        if(rightNodeIndex<size && arr[rightNodeIndex]>arr[maxIndex]) {
            maxIndex=rightNodeIndex;
        }
        //来调换位置
        if(maxIndex!=index) {
            int temp=arr[maxIndex];
            arr[maxIndex]=arr[index];
            arr[index]=temp;
            //调换完之后,可能会影响到下面的子树,不是大顶堆,所以还需要再次调换
            toMaxHeap(arr,size,maxIndex);
        }
    }
}

Java数组与八大排序_第20张图片

你可能感兴趣的:(Java笔记,java,排序算法,算法)