java中的一些常见排序算法

//在相信不管是做java开发还是android开发,对于排序都是非常的熟悉,下面我们来分别讨论一下各种常见的简单排序——冒泡排序,插入排序,选择排序,快速排序,归并排序。

public class TestJson {


    public static void main(String[] args){
        int[] a = {2,4,253,66565,76,43,543,532,432};
//      popuSort(a);
//      
//      selectSort(a);

//      quickSort(a, 0, 8);
//      
//      mergeSort(a, 0, 8);
//      
        insertSort(a);

        for(int x : a){
            System.out.print("  " + x);
        }
    }
    //1,冒泡排序:
    /**
     * 冒泡排序:中心思想就是首先第一轮循环遍历整个数组,然后第二轮循环从第一轮循环的基础上,从他的下一个元素开始跟 它进行比较,
     * 如果出现比他大(这里是实现从小到大的排序)的元素,那么这两个元素的值互换,也就是每次都在剩下的元素里面选出最小的元素,并且
     * 跟当前循环的起始元素值进行交换,外层循环从0开始,就保证了每一轮循环的第一个值都是当前的最小值,循环结束,就把所有“最小元素”
     * 进行了一次完整排序,从小到大。两层循环结束就完成了排序。
     * 
     * @param data
     */
    public static void popuSort(int[] data) {
        for (int i = 0; i < data.length; i++) {
            int tempIndex = i;
            for (int j = i + 1; j < data.length; j++) {
                if (data[tempIndex] > data[j]) {
                    int temp = data[tempIndex];
                    data[tempIndex] = data[j];
                    data[j] = temp;
                }
            }
        }
    }

    // 2,选择排序
    /**
     * 选择排序:中心思想就是首先第一轮循环遍历整个数组,然后第二轮循环从第一轮循环的基础上,从他的下一个元素开始跟它进行比较,
     * 如果出现比他大(这里是实现从小到大的排序)的元素,记录下来这个比较小的元素的下标,直到每层循环结束就记录下来了剩下的i开
     * 始的最小元素下标。并且与当前循环的其起始元素互换,就保证了每一轮循环的第一个值都是当前的最小值,循环结束,就把所有“最小元素”
     * 进行了一次完整排序,从小到大。两层循环结束就完成了排序。
     * 
     * @param data
     */
    public static void selectSort(int[] data) {
        for (int i = 0; i < data.length; i++) {
            int tempIndex = i;
            for (int j = i + 1; j < data.length; j++) {
                if (data[j] < data[tempIndex]) {
                    tempIndex = j;
                }
            }
            int temp = data[tempIndex];
            data[tempIndex] = data[i];
            data[i] = temp;
        }
    }

    // 其实冒泡排序跟选择排序的思想是差不多的,只是选择排序是记录下最小元素下标,内层循环完成才互换,跟冒泡排序相比少了互换的次数

    // 3,插入排序
    /**
     * 插入排序:每次都是把后一个元素跟前面已经排好序的数组进行比较插入,为了保证前面的元素都已经是排好序的,当元素只有一个的时候,我们可以
     * 认为是已经排好序的只有一个元素的数组,所以i从1开始。跟他前面的已经排好序的数组进行比较,如果如果data[j]>data[i]就继续往下比较,
     * 因为是已经按从小到大排好序的数组,所以我们只要找到比他小的元素就可以停止了,因为是递增的。
     * 
     * @param data
     */
    public static void insertSort(int[] data) {
        for (int i = 1; i < data.length; i++) {
            int j = i - 1;
            int temp = data[i];
            while (j >= 0 && data[j] > temp) {
                data[j + 1] = data[j];
                j--;
            }
            data[j + 1] = temp;
        }
    }

    // 以下是快速排序和归并排序,因为都是递归排序,所以放到一起。因为是递归,所以才要指明循环的起始位置,不然我们就
    // 就可以使用0和data.length来循环,因为内层是小数组递归,所以这时候就无法使用这个,我们要把其实的循环位置作为参数
    // 传入到函数里面去。

    // 4,快速排序
    /**
     * 快速排序:任意选取一个基准数,这里选为base=data[start],为实现从小到大的排序,数组的左边放置比base小的数,
     * 右边放置比base大的数字 然后从数组的两边开始遍历数组。 左边到右边遍历,直到出现>=base的数字停止遍历。i++
     * 右边到左边遍历,直到出现<=base的数字停止遍历。j--
     * 在两边都停止遍历之后,如果i<=j就把data[i]和data[j]的值进行互换,使的数组左边的数都是小于等于base的数
     * 右边的都是大于等于base的数
     * 。这样一轮下来当然无法完成全部的排序,我们只是保证了左边的元素都<=base,右边的数都>=base,而没有准确的排序,
     * 所以我们再继续对两边的数组进行这样的排序,直到数组值剩下一个元素的时候,递归返回,就完成了全部的排序。
     * 
     * @param data
     * @param start
     * @param end
     */
    public static void quickSort(int[] data, int start, int end) {
        int i = start;
        int j = end;
        int base = data[start];
        while (i <= j) {
            while (data[i] < base) {
                i++;
            }
            while (data[j] > base) {
                j--;
            }
            if (i <= j) {
                int temp = data[i];
                data[i] = data[j];
                data[j] = temp;
                i++;
                j--;
            }
        }
        if (start < j) {
            quickSort(data, start, j);
        }
        if (i < end) {
            quickSort(data, i, end);
        }
    }

    // 归并算法实现:
    /**
     * 归并算法:把两个已经排好序的数组再合并到一个排好序的大一点的数组,这个新的数组是new的一个大小跟两个数组长度之和相等的一
     * 个数组,用来放置排好序的大数组。从两个数组的起始位置分别开始循环,比较得到小的元素就放入到新的数组里面,比较到最后把还没有放完的数组
     * 一次放到数组的后面。
     * 
     * @param data
     * @param start
     * @param center
     * @param end
     */
    public static void merge(int[] data, int start, int center, int end) {
        int left = start;
        int mid = center + 1;
        int newArrayIndex = start;
        int tmp = start;
        int[] newArray = new int[data.length];
        while (left <= center && mid <= end) {
            if (data[left] > data[mid]) {
                newArray[newArrayIndex++] = data[mid++];
            } else {
                newArray[newArrayIndex++] = data[left++];
            }
        }
        while (left <= center) {
            newArray[newArrayIndex++] = data[left++];
        }
        while (mid <= end) {
            newArray[newArrayIndex++] = data[mid++];
        }

        while (tmp <= end) {
            data[tmp] = newArray[tmp++];
        }
    }

    // 5,归并排序。其实是分治法的一个典型实例首先看一下百度百科的解释把:
    // 分治法可以通俗的解释为:把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什
    // 么,然后让他们彼此异化。
    // 分治法的精髓:
    // 分--将问题分解为规模更小的子问题;
    // 治--将这些规模更小的子问题逐个击破;
    // 合--将已解决的子问题合并,最终得出“母”问题的解;

    /**
     * 归并排序:把数组进行拆分,拆分到只有一个元素的时候停止,递归返回,从内到外,把所有排好序的小数组进行归并,直到
     * 返回到最外层,就完成了所有的归并,实现排序。
     * 
     * @param data
     * @param start
     * @param end
     */
    public static void mergeSort(int[] data, int start, int end) {
        if (start >= end) {
            return;
        }
        int center = (start + end) / 2;

        mergeSort(data, start, center);

        mergeSort(data, center + 1, end);

        merge(data, start, center, end);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值