十大经典排序算法的java实现以及原理讲解

本文详细介绍并提供了十大经典排序算法的Java实现,包括冒泡排序、选择排序、插入排序等,适合学习与实践。

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

首先,这篇博客的来源是因为我在学习排序算法的时候,看到了一位大神写的十大经典排序算法,写的真的很不错,可是遗憾的是没有java版本实现,所以我按照每个排序来写了一个java版本实现,如有错误,欢迎指正。

所以说,学习这篇文章时,建议和十大经典排序算法一起看。

1、冒泡排序

package cn.yqh.interview.sort;


/**
 * @author 袁
 * @create 2019/8/27-15:27
 */
public class BubbleSort {
    public static int[] bubbleSort(int[] array) {
        if (array == null || array.length == 0) {
            return null;
        }
        for (int i = 0; i < array.length - 1; i++) {    //控制比较的次数,比较次数为数组长度减一
            for (int j = 0; j < array.length - 1 - i; j++) {     //每次都是相邻两个比较
                if (array[j] < array[j + 1]) {    //<就代表每次把小的数据往上排
                    swap(array, j, j + 1);
                }
            }
        }
        return array;
    }

    private static void swap(int[] arr, int i, int i1) {
        int tem = arr[i];
        arr[i] = arr[i1];
        arr[i1] = tem;
    }

    public static void main(String[] args) {
        int[] arr = {5, 3, 7, 2, 9, 4, 1};
        int[] sort = bubbleSort(arr);
        for (int i : sort) {
            System.out.print(i + " ");
        }
    }
}

2、选择排序

package cn.yqh.interview.sort;


/**
 * @author 袁
 * @create 2019/8/27-15:27
 */
public class SelectionSort {
    public static int[] selectionSort(int[] array) {
        if (array == null || array.length == 0) {
            return null;
        }
        for (int i = 0; i < array.length - 1; i++) {      //需要比较的次数,数组长度减一次
            //先假设每次循环时,最小(大)数的索引为i
            int minIndex = i;
            //每一个元素都和剩下的未排序的元素比较
            for (int j = i + 1; j < array.length; j++) {
                if (array[minIndex] > array[j]) minIndex = j;      //第一次写代码犯错:每比较一次,就交换一次,这样显然没有记录最小值的索引然后在最后交换一次的好
            }                                                      //第二次写代码犯错:这里应该是array[minIndex] > array[j]比较,而不是array[i] > array[j]比较

            //进过一轮循环,即可找出第一个最值的索引,然后把最值放到i的位置
            swap(array, i, minIndex);

        }
        return array;
    }

    private static void swap(int[] arr, int i, int i1) {
        int tem = arr[i];
        arr[i] = arr[i1];
        arr[i1] = tem;
    }

    public static void main(String[] args) {
        int[] arr = {5, 3, 7, 2, 9, 4, 1};
        int[] sort = selectionSort(arr);
        for (int i : sort) {
            System.out.print(i + " ");
        }
    }
}

3、插入排序

package cn.yqh.interview.sort;


/**
 * @author 袁
 * @create 2019/8/27-15:27
 */
public class InsertionSort {


//    版本1,双for循环
    public static int[] insertionSort(int[] array) {

        int current, index;

        if (array == null && array.length == 0) {
            return null;
        }
        for (int i = 1; i < array.length; i++) {

            current = array[i];             //取出元素
            index = i;                      //记下当前元素的索引位置

            for (int j = i - 1; j >= 0; j--) {
                if (current < array[j]) {
                    array[j + 1] = array[j];      //将这个较大的结点后移
                    index = j;      //通过index记下current将要放置的位置
                }
            }
            if (index != i) array[index] = current;           //如果array刚刚好是有顺序的,则到这里时,这个元素就不用移动了
        }
        return array;
    }

//    版本2,for循环加while循环(大众版本)
    public static int[] insertionSort2(int[] array) {

        int current, index, j;

        if (array == null || array.length == 0) {
            return null;
        }
        for (int i = 1; i < array.length; i++) {

            current = array[i];             //取出元素,避免若前面的元素小于当前元素,前面元素后移导致当前元素被覆盖
            index = i;                      //记下当前元素的索引位置
            j = i-1;                        //记录当前元素的前一个元素的位置

            while (j >= 0 && array[j] > current) {
                array[j+1] = array[j];      //元素后移
                index = j--;                //先赋值再减减(j--就是继续往前寻找组中前面的元素)

            }
            if (index != i) array[index] = current;           //如果array刚刚好是有顺序的,则到这里时,这个元素就不用移动了
            //也可以不适用index,直接用最后的j+1,其实和index是一样的,这里加入index为了更好理解
        }
        return array;
    }


    public static void main(String[] args) {
        int[] arr = {5, 3, 7, 2, 9, 4, 1};
        int[] sort = insertionSort2(arr);
        for (int i : sort) {
            System.out.print(i + " ");
        }
    }
}

4、希尔排序

package cn.yqh.interview.sort;

/**
 * @author 袁
 * @create 2019/8/27-19:33
 */
public class ShellSort {


    public static int[] shellSort(int[] array) {

        int current, index, j;

        if (array == null || array.length == 0) {
            return null;
        }

        for (int gap = array.length / 2; gap > 0; gap = gap / 2) {      //选取gap,采用推荐的默认/2取gap的方式
            for (int i = gap; i < array.length; i++) {        //需要排序的组数
                //接下来采用插入排序对每个组进行排序
                current = array[i];     //取出当前元素,避免前组中前一个元素后移导致此元素被覆盖
                j = i - gap;            //取得这个组中的前一个元素的位置
                while (j >= 0 && array[j] > current) {
                    array[j + gap] = array[j];        //元素后移,注意移动的个数为gap,第一次编程写错了array[j + 1] = array[j];
                    j -= gap;                       //j继续往前寻找组中前面的元素
                }
                array[j + gap] = current;             //j+gpa即为array[i]该移动的位置
            }
        }

        return array;
    }


    public static void main(String[] args) {
        int[] arr = {5, 3, 7, 2, 9, 4, 1};
        int[] sort = shellSort(arr);
        for (int i : sort) {
            System.out.print(i + " ");
        }
    }
}



5、归并排序

package cn.yqh.interview.sort;

/**
 * @author 袁
 * @create 2019/8/27-19:33
 */
public class MergeSort {


    public static int[] sort(int[] a, int low, int high) {
        int mid = (low + high) / 2;
        if (low < high) {
            sort(a, low, mid);
            sort(a, mid + 1, high);
            merge(a, low, mid, high);
        }
        return a;
    }

    public static void merge(int[] a, int low, int mid, int high) {
        if (a == null || a.length == 0) {
            return;
        }

        int[] temp = new int[high - low + 1];
        int k = 0;          //记录temp数组的下标
        int i = low, j = mid + 1;           //定义两个指针,i指向前一半的第一个元素的位置,j指向mid+1的位置
        while (i <= mid && j <= high) {
            if (a[i] < a[j]) {
                temp[k++] = a[i++];
            } else {
                temp[k++] = a[j++];
            }
        }

        while (i <= mid) {
            temp[k++] = a[i++];
        }


        while (j <= high) {
            temp[k++] = a[j++];
        }

        for (int l = 0; l < temp.length; l++) {
            a[low + l] = temp[l];
        }
    }


    public static void main(String[] args) {
        int[] arr = {5, 3, 7, 2, 9, 4, 1};
        int[] sort = sort(arr, 0, 6);
        for (int i : sort) {
            System.out.print(i + " ");
        }

    }
}



6、快速排序

package cn.yqh.interview.sort;

/**
 * @author 袁
 * @create 2019/8/28-15:47
 * https://blog.csdn.net/Yexiaofen/article/details/78018204
 */
public class QuickSort {
    public static void quickSort(int[] a, int low, int high) {
        if (a == null || a.length == 0) {
            return;
        }
        //1,找到递归算法的出口
        if (low > high) {
            return;
        }
        //2, 存
        int i = low;
        int j = high;
        //3,key
        int key = a[low];
        //4,完成一趟排序
        while (i < j) {
            //4.1 ,从右往左找到第一个小于key的数
            while (i < j && a[j] > key) {
                j--;
            }
            // 4.2 从左往右找到第一个大于key的数
            while (i < j && a[i] <= key) {
                i++;
            }
            //4.3 交换
            if (i < j) {
                int p = a[i];
                a[i] = a[j];
                a[j] = p;
            }
        }
        // 4.4,调整key的位置
        swap(a, i, low);
        //5, 对key左边的数快排
        quickSort(a, low, i - 1);
        //6, 对key右边的数快排
        quickSort(a, i + 1, high);

    }

    private static void swap(int[] arr, int i, int i1) {
        int tem = arr[i];
        arr[i] = arr[i1];
        arr[i1] = tem;
    }

    public static void main(String[] args) {
        int[] arr = {22, 3, 0, 85, 7, 6, 25, 24, 56, 22};
        quickSort(arr, 0, arr.length - 1);
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }
}

7、堆排序

package cn.yqh.interview.sort;

/**
 * @author 袁
 * @create 2019/8/27-19:33
 * https://www.jianshu.com/p/11655047ab58
 */
public class HeapSort {


    /**
     * 堆排序
     */
    public static void heapSort(int[] arr) {
        if (arr == null || arr.length == 0) {
            return;
        }
        //对初始的数组构造大顶堆
        //对最后一个非叶子结点开始到根节点为止进行排序,使数组构成大顶堆
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            //调用headADjust排序
            headAdjust(arr, arr.length, i);
        }
        //排序完成,大顶堆已构成
        //依次取出根元素与最后第一个元素,最后第二个元素,最后第三个元素...交换位置(根元素此时已经最大)
        for (int i = arr.length - 1; i >= 1; i--) {
            swap(arr, 0, i);
            //交换之后,此时的根元素就一定是最大的元素了,所以进行堆调整,使根元素再次最大
            headAdjust(arr, i, 0);      //此时由于数组已经排出了一个最大元素放在最后,所以我们 只对剩下的length--进行排序,故长度为i
        }
    }


    /**
     * @param arr 需要排序的数组
     * @param len 数组的长度
     * @param i   需要排序的结点的索引
     *            <p>
     *            把要进行调整的结点i当做根节点,进行调整
     */
    private static void headAdjust(int[] arr, int len, int i) {
        if (arr == null || arr.length == 0) {
            return;
        }
        //把要进行调整的结点i当做根节点,则children
        int root = i, index = 2 * root + 1;    //index指向root直接结点中的最大值
        while (index < len) {       //当我们假设的这个左孩子存在时
            if (index + 1 < len) {       //如果这个右孩子也存在
                if (arr[index] < arr[index + 1]) index = index + 1;
            }
            //到这里就找到了root的孩子的最大值的索引
            if (arr[index] > arr[root]) {
                swap(arr, index, root);
            }
            //交换完之后继续把被交换的子节点变为父节点继续调整,因为交换操作可能会破坏堆
            //这里应该注意到,当操作树的倒数第二层,也就是非叶子结点的倒数第一层时,运行到这里while就结束了
            //但是如果是倒数第三次或者更高时,那么下面的倒数第二层已经是被排序过了的
            root = index;
            index = 2 * root + 1;

            //这里可以改成这样,若交换了则继续更新下面的节点,没交换则不用更新
            /*if (arr[index] > arr[root]) {
                swap(arr, root, index);
                root = index;
                index = 2 * root + 1;
            } else {
                break;
            }*/
        }
    }


    private static void swap(int[] arr, int i, int i1) {
        int tem = arr[i];
        arr[i] = arr[i1];
        arr[i1] = tem;
    }

    public static void main(String[] args) {
        int[] arr = {5, 3, 7, 2, 9, 4, 1};
        heapSort(arr);
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }
}



8、计数排序

package cn.yqh.interview.sort;

/**
 * @author 袁
 * @create 2019/8/27-19:33
 * https://www.cnblogs.com/zer0Black/p/6169858.html
 */

public class CountingSort {


    /**
     * 堆排序
     */
    public static void countingSort(int[] arr) {
        if (arr == null || arr.length == 0) {
            return;
        }

        int max = 0, min = 0;

        //找出数组中最大最小值
        for (int i = 0; i < arr.length; i++) {
            max = Math.max(max, arr[i]);
            min = Math.min(min, arr[i]);
        }

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

        //对数组中每个出现的元素计数
        for (int i = 0; i < arr.length; i++) {
            count[arr[i] - min]++;
        }

        //然后通过count数组得到数据的顺序
        int index = 0;
        for (int i = 0; i < count.length; i++) {
            while (count[i]-- > 0) {        //这里count[i]先与0比较,后--
                arr[index++] = i + min;        //这里arr[index]=i+min之后,index再++
            }
        }

    }


    public static void main(String[] args) {
        int[] arr = {5, 5, 3, 7, 2, 9, 4, 1};
        countingSort(arr);
        for (int i : arr) {
            System.out.print(i + " ");
        }

    }
}



9、桶排序

package cn.yqh.interview.sort;

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

/**
 * @author 袁
 * @create 2019/8/27-19:33
 * https://www.cnblogs.com/zer0Black/p/6169858.html
 */

public class BucketSort {


    /**
     * 桶排序
     */
    public static List bucketSort(int[] arr) {
        if (arr == null || arr.length == 0) {
            return null;
        }

        int max = 0, min = 0;

        //找出数组中最大最小值
        for (int i = 0; i < arr.length; i++) {
            max = Math.max(max, arr[i]);
            min = Math.min(min, arr[i]);
        }

        // 先计算桶的数量
        int bucketCount = (max - min) / arr.length + 1;
        //创建桶数组
        ArrayList<ArrayList<Integer>> bucketArray = new ArrayList<ArrayList<Integer>>(bucketCount);
        for (int i = 0; i < bucketCount; i++) {
            bucketArray.add(new ArrayList<Integer>());
        }
        //把数据放入桶中
        for (int i = 0; i < arr.length; i++) {
            bucketArray.get((arr[i] - min) / arr.length).add(arr[i]);
        }
        //对每个桶中的数据排序
        for (int i = 0; i < bucketArray.size(); i++) {
            Collections.sort(bucketArray.get(i));
        }
        return bucketArray;
    }


    public static void main(String[] args) {
        int[] arr = {5, 5, 3, 7, 2, 9, 4, 1};
        ArrayList list = (ArrayList) bucketSort(arr);
        System.out.println(list.toString());
    }
}



10、基数排序

package cn.yqh.interview.sort;

/**
 * @author 袁
 * @create 2019/8/27-19:33
 * https://www.cnblogs.com/developerY/p/3172379.html
 */

public class RadixSort {


    /**
     * 基数排序
     */
    public static void RadixSort(int[] arr, int maxDigit) {
        if (arr == null || arr.length == 0) {
            return;
        }

        int mod = 1;           //n取1,10,100...
        int k = 0;              //当把桶中的数据取出到arr时使用
        int len = arr.length;
        int[][] bucket = new int[10][len];      //桶,用来装每个数据
        int[] count = new int[10];             //用来记每个桶中有几个数据

        while (mod < maxDigit) {
            //把当前的数据按照顺序存到桶中
            for (int i : arr) {
                int digit = (i / mod) % 10;
                bucket[digit][count[digit]] = i;
                count[digit]++;
            }

            //一次排序完,则把数据从桶中放回数组中,
            for (int i = 0; i < count.length; i++) {
                if (count[i] != 0) {        //如果这个桶有数据,则取出
                    for (int j = 0; j < count[i]; j++) {
                        arr[k++] = bucket[i][j];
                    }
                }
                //每遍历完一个桶,把计数器归零
                count[i] = 0;
            }
            mod *= 10;             //继续比较下一位
            k = 0;
        }

    }


    public static void main(String[] args) {
        int[] arr = {5555, 5, 3, 7, 2, 999, 4, 1};
        RadixSort(arr, 10000);
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }
}



以上便是这是个算法的java实现版本,再次鸣谢大佬的分享:https://www.cnblogs.com/onepixel/articles/7674659.html

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值