八种排序

冒泡排序

冒泡排序的思路:
冒泡需要两个for循环:外面的for循环表示需要循环的次数,为数组的长度,里层的for循环是来选择数组中的最大值。
比如第一个循环后,最大的数就被排到数组的最后面,第二个循环后,第二大的数就被选出来排到后面。。。。等等,完成排序。

代码

package com.wuxudong.sort;

import java.util.Arrays;

//冒泡排序
public class BubbleSort {

    public static void main(String[] args) {
        //定义数组
        int [] arr=new int []{1,3,2,45,3,24,25};

        //定义排序方法
        bubbleSort(arr);

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

    }

    private static void bubbleSort(int[] arr) {

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

        }

    }

}

快速排序

思路:选择一个标准值,将数组中比标准数大的排到数组的后面,比标准数小的排到数组的前面,然后利用递归完成排序。

举个例子:对于这样一个数组我们选取3为标准值,并取两个指针用于遍历
start表示数组开始排序的位置,end表示数组结束排序的位置。

			//定义两个位置点,高和低
            int low=start;
            int high=end;

            //定义标准点
            int stard=arr[low];

在这里插入图片描述

  1. 判断arr[high]=6>3
    这时候满足条件,无需交换数的位置。并把high的指针往前移动一格
while (low<high&&stard<=arr[high]){
                    high=high-1;
 }

在这里插入图片描述
2. 判断arr[high]❤️
这是不满足条件,需要把3替换成2.

 arr[low]=arr[high];

在这里插入图片描述
3. 移动low指针 判断arr[low]=5>3,不满足条件将high指针的2替换成5
在这里插入图片描述

			 while (low<high&&arr[low]<=stard){
                    low++;
                }
                arr[high]=arr[low];

然后,high指针向前移一步。判断arr[high]=1<3,不满足条件
在这里插入图片描述
移动low指针,判断arr[low]=8>3不满足条件,arr[high]=arr[low]
在这里插入图片描述
移动high指针,判断arr[high]=5>3满足条件。再移动high指针arr[high]=9>3,满足条件。在移动指针arr[high]=8>3,满足条件。此时low==high,循环结束。并将标准值赋值给arr[low]
在这里插入图片描述

 arr[low]=stard;

至此,我们可以看出整个数组被分为两部分,比3小的和比3大的。
在这里插入图片描述
这时,我们调用递归,分别对这两部分进行排序

			 //递归
            quickSort(arr,start,low);
            quickSort(arr,low+1,end);

递归结束的条件是start<end

整个代码

package com.wuxudong.sort;

import java.util.Arrays;

public class QuickSort {

    public static void main(String[] args) {

        int [] arr=new int []{4,3,2,45,3,24,25};

        //启用排序方法
        quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }

    private static void quickSort(int[] arr, int start, int end) {
        if(start<end){
            //定义两个位置点,高和低
            int low=start;
            int high=end;

            //定义标准店
            int stard=arr[low];

            //循环
            while (low<high){

                while (low<high&&stard<=arr[high]){
                    high=high-1;

                }
                arr[low]=arr[high];

                while (low<high&&arr[low]<=stard){
                    low++;
                }
                arr[high]=arr[low];

            }
            arr[low]=stard;

            //递归
            quickSort(arr,start,low);
            quickSort(arr,low+1,end);

        }



    }

}

插入排序

package com.wuxudong.sort;

import java.util.Arrays;

public class InsertSort {

    public static void main(String[] args) {
        //定义数组
        int [] arr=new int []{3,3,2,45,3,24,34,67,1,25};

        insertSort(arr);

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

    private static void insertSort(int[] arr) {

        for (int i = 1; i < arr.length; i++) {
            //如果后面一个数比前面的数小就需要交换位置
            if(arr[i]<arr[i-1]){
                //存储当前数的临时变量
                int temp=arr[i];

                int j=0;


                for (j=i-1;j>=0&&temp<arr[j];j--){
                    //如果前一个数比临时变量大,则需要往后移一个位置
                    arr[j+1]=arr[j];
                }
                //如果前面的数比临时变量小,则循环结束,将临时值赋值给前面数的后面一个位置
                arr[j+1]=temp;

            }

        }

    }


}

希尔排序

希尔排序是对插入排序的优化,因为在插入排序中较小的数再后面的话,需要交换很多次,才能将它移动数组前面,较大的数也是同理,因此,希尔排序通过定义步长来进行分组插入排序,可以先将较小的数快速的放到前面,较大的数快速的放到后面。

package com.wuxudong.sort;


import java.util.Arrays;

//希尔排序
public class ShellSort {

    public static void main(String[] args) {
        int [] arr=new int []{3,3,2,45,3,24,34,67,1,25};

        shellSort(arr);

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

    private static void shellSort(int[] arr) {

        //遍历所有步长
        for (int d=arr.length/2;d>0;d=d/2){
            //对分组后的数组进行插入排序
            for (int i = d; i <arr.length ; i++) {

                for (int j=i-d;j>=0;j=j-d){

                    if(arr[j]>arr[j+d]){
                        int temp=arr[j];
                        arr[j]=arr[j+d];
                        arr[j+d]=temp;
                    }
                }

            }

        }
    }

}

选择排序

思路与冒泡相同,冒泡选的是最大的,选择选的是最小的

package com.wuxudong.sort;

import java.util.Arrays;

public class SelectSort {

    public static void main(String[] args) {
        int [] arr=new int [] {3,3,2,45,3,24,34,67,1,25};

        selectSort(arr);

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

    private static void selectSort(int[] arr) {

        for (int i=0;i<arr.length;i++){
            int minIndex=i;

            for (int j=i+1;j<arr.length;j++){
                //找出最小的数
                if (arr[j]<arr[minIndex]){
                    minIndex=j;
                }

            }

            if(i!=minIndex){
                int temp=arr[i];
                arr[i]=arr[minIndex];
                arr[minIndex]=temp;

            }

        }
    }


}

归并排序

归并排序里利用了归并的思想,即将两个排序好的数组按大小归并到一个数组中。利用递归的思想,将数组差分成不可再分两个数,这两个数可以看作两个排好序的数组,进行归并,最后将递归将其它的数进行归并,完成排序。

package com.wuxudong.sort;


import java.util.Arrays;

//归并排序
public class MergeSort{

    public static void main(String[] args) {
        int [] arr=new int[]{3,3,2,45,3,24,34,67,1,25};

        mergeSort(arr,0,arr.length-1);

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

    private static void mergeSort(int[] arr, int low, int high) {
        if(low<high){
            int middle=(low+high)/2;
            mergeSort(arr,low,middle);
            mergeSort(arr,middle+1,high);
            merge(arr,low,middle,high);
        }


    }

    //归并方法

    /**
     *
     * @param arr 传入的数组
     * @param low 第一个数组开始的下标
     * @param middle 第一个数组结束的下标
     * @param high  第二个数组结束的下标
     */
    public static void merge(int [] arr,int low,int middle,int high){
        //新建一个临时数组,用来存储归并后的数组
        int [] temp=new int [high-low+1];

        //记录第一个数组中需要遍历的下标
        int i=low;

        //记录第二个数组中需要遍历的下标
        int j=middle+1;

        //临时数组的下标
        int index=0;

        //遍历两个数组取出最小的数字,放入临时数组中
        while (i<=middle&&j<=high){
            if(arr[i]<=arr[j]){
                //第一个数组中的值小
                temp[index]=arr[i];
                i++;
            }else {
                //第一个数组中的值大
                temp[index]=arr[j];
                j++;
            }
            index++;

        }

        //将剩余的数添加到临时数组中
        if(i>middle) {
            //第一个数组遍历完了
            while (j <= high) {
                temp[index] = arr[j];
                j++;
                index++;
            }
        }


        if (j>high) {
            //第二个数组遍历完了
            while (i <= middle) {
                temp[index] = arr[i];
                i++;
                index++;
            }
        }

        //将临时数组的值赋值给原数组
        for (int k = 0; k <temp.length ; k++) {
            arr[k+low]=temp[k];
        }

    }

}

基数排序

基数排序的思想比较简单,实际上就是按照先较个位,再比较十位等等的思想来进行排序。
举个例子
在这里插入图片描述
对于这样一个数组,我们先找出其中的最大值798,并判断它是几位数,是几位数我们就要循环几次。

第一次循环:将个位数是几的数放到对应几的数组中
在这里插入图片描述
然后将数组里的这些数依次按照存入的顺序取出来

在这里插入图片描述
第二次循环:将十位数是几的数放到对应几的数组中
在这里插入图片描述
然后再依次取出来
在这里插入图片描述
第三次循环:将百位数是几的数放到对应几的数组中

在这里插入图片描述
最后,依次取出来完成排序
在这里插入图片描述

代码:

package com.wuxudong.sort;

import java.util.Arrays;

//基数排序
public class RadixSort {

    public static void main(String[] args) {
        int [] arr=new int [] {23,6,189,45,9,287,56,1,798,35,65,652,5};
        radixSort(arr);
        System.out.println(Arrays.toString(arr));

    }

    public static void radixSort(int [] arr){

        int maxValue=Integer.MIN_VALUE;
        //第一步:找出数组中最大的数字
        for (int i=0;i<arr.length;i++){
            if(arr[i]>maxValue){
                maxValue=arr[i];
            }
        }

        //得到最大数是几位数
        int num=(maxValue+"").length();

        //定义二维数组存储变量值
        int [][] temp=new int[10][arr.length];

        //定义一个数组来表示存入数组的个数
        int [] counts=new int [10];


        //循环遍历,循环的次数,n用来取个位,十位,百位。
        for (int i = 0,n=1; i < num; i++,n=n*10) {

            //循环遍历数组
            for (int j=0;j<arr.length;j++){
                int ys=arr[j]/n%10;
                temp[ys][counts[ys]]=arr[j];
                counts[ys]++;

            }

            //定义一个变量表示原数组的下标
            int index=0;
            //取出对应的元素
            for (int k=0;k<10;k++){
                if(counts[k]!=0){
                    for (int l=0;l<counts[k];l++){
                        arr[index]=temp[k][l];
                        index++;
                    }

                    //将数量置为0,留着给下个循环使用
                    counts[k]=0;

                }

            }

        }




    }

}

堆排序

利用了二叉树的数据结构。任何一个数组都可以表示为一个唯一的完全二叉树,任何一个完全二叉树都可以表示为一个数组。我们将数组表示为一个二叉树,然后对把这个二叉树转成大顶堆(即父节点大于子节点),这样根节点就是数组中最大的数,我们在将二叉树的最后一个叶子节点和根节点进行交换,在转为大顶堆,这个第二大的数也找出来了,依次循环,完成排序。

package com.wuxudong.sort;

import java.util.Arrays;

//堆排序
public class HeapSort {

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

    public static void heapSort(int [] arr){
        //开始的位置是最后一个非叶子节点,即最后一个节点的父节点
        int start=(arr.length-1)/2;
        //调整大顶堆
        for (int i=start;i>=0;i--){
            maxHeap(arr,arr.length,i);
        }

        //先把数组中的第0个和堆中的最后一个数交换位置,再把前面的处理为大顶堆
        for (int i = arr.length-1; i>0 ; i--) {
            int temp=arr[0];
            arr[0]=arr[i];
            arr[i]=temp;
            maxHeap(arr,i,0);
        }


    }

    //将数组转为大顶堆
    public static void maxHeap(int [] arr,int size,int index){

        //左节点
        int leftNode=2*index+1;

        //右节点
        int rightNode=2*index+2;

        //定义最大的节点
        int max=index;

        if(leftNode<size&&arr[leftNode]>arr[max]){
            max=leftNode;
        }
        if (rightNode<size&&arr[rightNode]>arr[max]){
            max=rightNode;
        }

        //交换位置
        if(max!=index){
            int temp=arr[index];
            arr[index]=arr[max];
            arr[max]=temp;

            //交换位置后,可能会破坏之前排好的堆,所以,之前排好的堆需要重新调整
            maxHeap(arr,size,max);

        }




    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值