排序算法原理及其Java代码(快速排序、冒泡排序、直接插入排序、简单选择排序)

package sort;
/**
 * 排序测试
 * @author lwj
 */
public class SortTest {


    public static void main(String[] args) {
        int[] arr = {9,8,7,6,5,4,3,2,1,0};
//      directInsert(arr);
//      bubbleSort(arr);
//      quickSort(arr, 0, arr.length-1);
        selectSort(arr);


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

    /**
     * 简单选择排序
     * @param arr
     * 原理:每一趟从待排序的元素中选出关键字最小的元素,顺序放在已排序的子表的最后,直到全部元素排序完毕(最傻瓜式的排序)
     */
    private static void selectSort(int[] arr) {
        for (int i = 0; i < arr.length-1; i++) {
            int min_index = i; //最小的值的角标
            for (int j = i+1; j < arr.length; j++) {
                if(arr[j] < arr[min_index]){
                    min_index = j;
                }
            }
            if(i != min_index){//严谨些多加个判断
                change(arr, i, min_index);//将最小值和第i个值进行互换
            }
        }
    }


    /**
     * 交换元素——快速排序
     * @param arr
     * 原理:选定一个数(一般是第一个),比这个数小的放到该数的前面,比这个数大的放到该数的后面
     */
    private static void quickSort(int[] arr, int begin, int end) {
        if(end - begin < 1)//只要两个角标还是重叠或者越过了对方,则return
            return;
        int flag = arr[begin]; //一般拿取第一个数作为后续对比的数
        int blank_index = begin;//空位置的角标,下面递归有用到
        for (int i = begin+1; i <= end; i++) {//这里的end就是arr.length-1
            if (arr[i] < flag) {//如果该数比flag小,则尽心移位          
                for (int j = i; j > blank_index; j--) {//注意终止for循环的条件为“j>blank_index”,因为要考虑当blank_index和j重叠时的情景
                    change(arr, j, j-1);
                }
                blank_index++;//空位的角标       
            }
        }
        arr[blank_index] = flag;//将flag插入到正确的位置
        quickSort(arr, begin, blank_index-1);//将左边的局部数组进行递归
        quickSort(arr, blank_index+1, end);//将右边的局部数组进行递归
    }


    /**
     * 交换元素——冒泡排序
     * @param arr
     * 原理:从底层开始,向上对比,如果比上一个小,那么就互换
     */
    private static void bubbleSort(int[] arr) {
        int length = arr.length;
        for (int i = 0; i < length -1; i++) {
            for (int j = length-1; j > i; j--) {
                if(arr[j] < arr[j-1])
                    change(arr, j-1, j);
            }
        }

    }

    /**
     * 直接插入排序
     * @param arr
     * 原理:将一个数组从第二个数开始,往后拿取数插入到前面合适的位置,只要保证该数之前的局部数组是有序的
     */
    private static void directInsert(int[] arr){
        for (int i = 1; i < arr.length; i++) {//从第二个数开始跟第一个数对比
            int j = i;
            while(j > 0 && arr[j-1] > arr[j]){//注意,要吧 j>0 放在 && 前面
                change(arr, j-1, j);
                j--;
            }
        }
    }

    /**
     * 交换元素
     * @param arr
     * @param a
     * @param b
     */
    private static void change(int[] arr, int a, int b){
//      int x = arr[a];
//      arr[a] = arr[b];
//      arr[b] = x;

        //不引入其他变量的情况下实现元素交换,注意,只有在a和b不相等的情况下才有用
        arr[a] = arr[a] + arr[b];
        arr[b] = arr[a] - arr[b];
        arr[a] = arr[a] - arr[b];
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值