十大排序算法 java 实现(可以跑通)

十大排序算法 java 实现(可以跑通)

网上关于十大排序算法的文章参差不齐,作者理解不同,注释不同,致使像我们这初学者理解起来不那么容易,所以我查阅了很多资料,整理以下十个排序算法的java实现。具有以下特点:

  • 代码用java实现,可以跑通
  • 代码加了很多注释,便于理解
  • 相关的排序算法加了相关的阅读文章,便于理解。
    希望能够帮助到你。

冒泡排序 插入排序 选择排序 希尔排序 快速排序 归并排序 堆排序 桶排序 计数排序 基数排序

希尔排序对应文章
快速排序
归并排序文章1
归并排序文章2
堆排序文章1
堆排序文章2
桶排序
计数排序1
计数排序2
基数排序

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @description:用于整理排序算法
 * @author: 12345ua
 * @create: 2021-10-15 20:05
 */
public class SortTest {

    /**
     *冒泡排序
     * 外循环控制总共循环的次数
     * 内循环控制进行具体的操作
     * @param a
     * @param n
     * @return
     */
    public void bubbleSort(int a[],int n){
        for (int i = 0; i < n-1; i++) {
            for (int j = 0; j < n-i-1; j++) {
                if(a[j]>a[j+1]){
                    int tmp=a[j];//交换
                    a[j]=a[j+1];
                    a[j+1]=tmp;
                }
            }
        }

    }


    public void bubbleSort1(int a[],int n){
        for (int i = n-1; i >=0; i--) {
            for (int j = 0; j < i; j++) {
                if(a[j]>a[j+1]){
                    int tmp=a[j];//交换
                    a[j]=a[j+1];
                    a[j+1]=tmp;
                }
            }
        }

    }

    /**
     * 选择排序
     * @param arr
     */
    public void selecttionSort(int arr[]){
        int len=arr.length;
        int minIndex=0;

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


}

    /**
     * 先找多少趟,然后再找切入点,w往后移动
     * 插入排序
     * @param a
     */
    public int[] InsertSort(int a[]){

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

}

    /**
     * 冒泡排序的改进
     * 快速排序
     * @param a
     */
    public void quickSort(int[] a,int low,int high){

        int p,i,j,temp;

        if(low>=high){
            return;
        }

        // p是基准数
        p = a[low];
        i=low;
        j=high;

        while(i<j){
            // 右边当发现小于p的值时   停止循环
            while(a[j]>=p && i<j){
                j--;
            }
            //左边发现 大于p的值时   停止操作
            while(a[i]<=p && i<j){
                i++;
            }

            temp=a[j];
            a[j]=a[i];
            a[i]=temp;

        }
        // 基准值和第一个元素发生位置互换
        a[low]=a[i];
        a[i]=p;

        // 对左边快排
        quickSort(a,low,j-1);
        // 对右边快排
        quickSort(a, j + 1, high);

        for (int i1 : a) {
            System.out.println(i1);
        }


}

    /**
     * 递归 自上而下创建堆
     * @param array
     * @param parent
     * @param length
     */
    public void adjustHeap1(int[] array,int parent,int length){
        // 左边子节点
        int left=2*parent+1;
        int right=2*parent+2;
        int bigger=left;// 记录节点较大的点的下标
        // 选择坐标大的子节点下标
        if (left < length - 1 && array[left] < array[right]) {
            bigger = right;
        }

        if (bigger > length - 1 || array[parent] >= array[bigger]) {
            return;
        }else{
            //  堆顶元素和左右子节点中较大的节点交换
            int temp = array[parent];
            array[parent] = array[bigger];
            array[bigger] = temp;
            adjustHeap1(array, bigger, length);
        }
}

    /**
     *自上而下构建大顶堆,将array看成完全二叉树的顺序结构
     * @param array
     * @return
     */
    public int[] buildMaxHeap(int[] array){
        // 从最后一个节点array.length-1-1 的父节点(array.length-1)/2开始,知道根节点0,反复调整堆
        for (int i = (array.length-2)/2; i >=0 ; i--) {
            adjustHeap1(array,i,array.length);
        }
        return array;
    }

    /**
     * 堆排序
     * @param array
     */
    public void heapSort(int[] array){
        // 初始化堆,array[0]为第一趟值最大的元素
        array = buildMaxHeap(array);
        // 将堆顶元素和堆底元素交换,即得到当前最大元素正确的排序位置
        for (int i = array.length-1; i >=1; i--) {
            int temp = array[0];
            array[0] = array[i];
            array[i] = temp;
            // 整理,将剩余的元素整理成大顶堆
            adjustHeap1(array, 0, i);
        }

        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }

    }


    /**
     * 合并数组
     * @param arrays 数组
     * @param left 指向数组的第一个元素
     * @param mid 指向数组分隔的元素
     * @param right 指向数组最后的元素
     */
    public void merge(int[] arrays,int left,int mid,int right){
        // 左边数组的大小
        int[] leftArray = new int[mid - left];
        // 右边数组
        int[] rightAyyay = new int[right - mid + 1];

        // 往这两个数组填充数据
        for (int i = left; i <mid ; i++) {
            leftArray[i-left]=arrays[i];
        }
        for (int i = mid; i <=right ; i++) {
            rightAyyay[i - mid] = arrays[i];
        }

        int i=0,j=0;
        // arrays数组的第一个元素
        int k = left;

        // 比较这两个数组的值,哪个小就往哪个数组上放
        while (i < leftArray.length && j < rightAyyay.length) {
            // 谁比较小,谁将元素放入到大数组中,移动指针,继续比较下一个
            // 等于是保证稳定
            if(leftArray[i]<=rightAyyay[j]){
                arrays[k] = leftArray[i];
                i++;
                k++;
            }else{
                arrays[k] = rightAyyay[j];
                j++;
                k++;
            }
        }

        // 如果左边的数组上还没有比较完,右边的数组都已经完了,那么将左边的数抄到大数组中(剩下的都是大数字)
        while (i < leftArray.length) {
            arrays[k] = leftArray[i];
            k++;
            i++;
        }
        //如果右边的数组还没比较完,左边的数都已经完了,那么将右边的数抄到大数组中(剩下的都是大数字)
        while (j < rightAyyay.length) {
            arrays[k] = rightAyyay[j];
            k++;
            j++;
        }

    }

    /**
     * 归并排序
     * @param arrays
     * @param left
     * @param right
     */
    public void mergeSort(int[] arrays, int left, int right) {
        //如果只有一个元素,那就不用排序
        if (left == right) {
            return;
        }else{
            // 取中间的数,进行拆分
            int mid = (left + right) / 2;
            // 左边的数不断进行拆分
            mergeSort(arrays, left, mid);
            // 右边的数不断碱性拆分
            mergeSort(arrays, mid + 1, right);
            // 合并
            merge(arrays, left, mid + 1, right);
        }

        for (int array : arrays) {
            System.out.println(array);
        }

    }

    /**
     * 希尔排序
     * @param arrays
     */
    public void shellSort(int[] arrays){

        int length = arrays.length;
        // 增量每次都是/2
        for (int step=length/2; step>0; step/=2) {
            //从增量那组开始插入排序,直至完毕
            for (int i = step; i <length ; i++) {
                // i代表即将插入的元素的角标,作为每一组比较数据的最后一个元素角标
                // j代表与i同一组的数组元素角标
                // 根据该比较序列的最后一个数的位置,依次向前执行插入排序
                // -step代表即将插入的元素的所在角标
                for (int j = i-step; j>=0 ; j=j-step) {
                    if(arrays[j]>arrays[j+step]){
                        int temp = arrays[j];
                        arrays[j] = arrays[j + step];
                        arrays[j + step] = temp;
                    }
                }
            }

        }

        for (int array : arrays) {
            System.out.println(array);
        }

    }

    /**
     *计数排序
     * @param a
     */
    public void CountSort(int[] a){
        int max=Integer.MIN_VALUE;
        int min=Integer.MAX_VALUE;

        // 找出最大值和最小值
        for (int i = 0; i < a.length; i++) {
            if (a[i] >max ) {
                max = a[i];
            }
            if (a[i] < min) {
                min = a[i];
            }
        }

        int[] help = new int[max - min + 1];

        // 找出每个数字出现的次数
        for (int i=0;i<a.length;i++) {
            int mapPos = a[i] - min;
            help[mapPos]++;
        }

        // 计算每个数字应该在排序后数组应该处于的位置
        for (int i = 1; i < help.length; i++) {
            help[i] = help[i-1] + help[i];
        }

        //根据help数组进行排序
        int[] res = new int[a.length];
        for (int i = 0; i < a.length; i++) {
            int post = --help[a[i] - min];
            res[post] = a[i];
        }

        for (int i : res) {
            System.out.println(i);
        }

    }

    /**
     * 桶排序
     * 把数组 arr 划分为n个大小相同子区间(桶),每个子区间各自排序,最后合并
     * @param a
     */
    public void bucketSort(int[] a) {
        int max=Integer.MIN_VALUE;
        int min=Integer.MAX_VALUE;

        // 找出最大值和最小值
        for (int i = 0; i < a.length; i++) {
            if (a[i] >max ) {
                max = a[i];
            }
            if (a[i] < min) {
                min = a[i];
            }
        }

        // 桶数
        int bucketNum = (max - min) / a.length + 1;
        List<ArrayList<Integer>> bucketArr = new ArrayList<>();
        for (int i = 0; i < bucketNum; i++) {
            bucketArr.add(new ArrayList<Integer>());
        }

        // 将每个元素放入桶
        for (int i = 0; i < a.length; i++) {
            int num = (a[i] - min) / a.length;
            bucketArr.get(num).add(a[i]);
        }

        // 对每个桶进行排序
        for (int i = 0; i < bucketArr.size(); i++) {
            Collections.sort(bucketArr.get(i));
        }

        System.out.println(bucketArr.toString());
    }


    /**
     * 基数排序
     * @param a
     */
    public void radixSort(int[] a){
        // 1.得到数组中的最大值,并获得该取值的位数,用于循环几轮
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < a.length; i++) {
            if (a[i] > max) {
                max = a[i];
            }
        }
        // 得到位数
        int maxLength = (max + "").length();
        // 定义桶 和桶标识元素的个数
        int[][] bucket = new int[10][a.length];
        int[] bucketCounts = new int[bucket.length];

        //总共需要进行 maxLength 轮
        for (int k = 1, n = 1; k <= maxLength; k++, n *= 10) {
            // 进行桶排序
            for (int i = 0; i < a.length; i++) {
                // 获取该轮的桶索引,每一轮按10的倍数递增,获取对应数位数
                // 这里额外使用一个步长为10的变量n来得到每次递增后的值
                int bucketIndex = a[i] / n % 10;
                // 放入该桶中
                bucket[bucketIndex][bucketCounts[bucketIndex]] = a[i];
                // 标识该桶元素多了一个
                bucketCounts[bucketIndex]++;
            }
            // 将桶中元素获取出来,放到原数组中
            int index=0;
            for (int i = 0; i < bucket.length; i++) {
                if (bucketCounts[i] == 0) {
                    // 该桶无有效元素,跳过不获取
                    continue;
                }
                // 获取桶中有效元素个数
                for (int j = 0; j < bucketCounts[i]; j++) {
                    a[index++]=bucket[i][j];
                }
                // 取完后,重置该桶的元素个数为0,下一次不会错乱数据
                bucketCounts[i] = 0;
            }

        }

        for (int ai : a) {
            System.out.println(ai);
        }

    }


    public static void main(String[] args) {

        int[] a={12,73,45,69,35,44};
        SortTest s = new SortTest();
//        s.mergeSort(a,0,a.length-1);
//        s.shellSort(a);
//        s.CountSort(a);
//        s.bucketSort(a);
        s.radixSort(a);

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值