排序

作者: 拙峰朽木 | 来源:发表于2018-04-20 23:16 被阅读10次

    蛮力法

    冒泡排序

    2的3次方以内的用冒泡排序

    private void BubbleSort(int[] array) {
            for (int j = array.length-1; j >0; j--) {
                boolean flag =true;
                for (int i = 0; i < j; i++) {
                    if (array[i] > array[i + 1]) {
                        flag=false;
                        int tmp =array[i+1];
                        array[i+1]=array[i];
                        array[i] =tmp;
                    }
                }
                if (flag){
                    break;
                }
            }
        }
    

    选择排序

    先定位再交换

    public class SelectSort {
        public static void selectSort(int[] array) {
            for (int i = 0; i < array.length - 1; i++) {
                //选出当前序列最小值的index
                int index = i;
                for (int j = i + 1; j < array.length; j++) {
                    if (array[index] > array[j]) {
                        index = j;
                    }
                }
                if (index != i) {
                    int tmp = array[index];
                    array[index] = array[i];
                    array[i] = tmp;
                }
            }
        }
    }
    

    递归

    斐波那契数列

    public static int FibonacciSequence(int i) {
            if (i == 1 || i == 2) {
                return 1;
            } else {
                return FibonacciSequence(i - 1) + FibonacciSequence(i - 2);
            }
        }
    
    

    调用;

     //斐波那契数列
            for (int i = 1; i < 11; i++) {
                System.out.println( Recursion.FibonacciSequence(i));
            }
    

    输出结果:
    1
    1
    2
    3
    5
    8
    13
    21
    34
    55

    汉诺塔

    有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:

    每次只能移动一个圆盘;
    大盘不能叠在小盘上面。
    提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则。

    
        private void hanoi(int n, int start, int middle, int end) {
            if (n == 1) {
                System.out.println(start + "---------------->" + end);
            } else {
                hanoi(n - 1, start, end, middle);
                System.out.println(start + "---------------->" + end);
                hanoi(n - 1, middle, start, end);
            }
        }
    
    

    调用:

    hanoi(3, 1, 2, 3);
    

    输出:

    1---------------->3
    1---------------->2
    3---------------->1
    1---------------->3
    2---------------->3
    2---------------->1
    3---------------->2

    分治法

    顺序查找

    二分查找

    首先这个序列必须是有序的

    int [] test ={1,2,3,4,7,9,10,12};
    
    /**
         * 二分查找  
         * @param array  数据
         * @param startIndex  开始位置交标
         * @param endIndex 结束位置交标
         * @param key 寻找的数字
         * @return 数字所在的交标  返回负值表示异常
         */
        private int binarySearch(int[] array, int startIndex, int endIndex, int key) {
            if (startIndex < 0 || endIndex < 0 || startIndex >= endIndex || endIndex > array.length) {
                return -1;
            }
            int low = startIndex;
            int high = endIndex-1;//遵循左闭右开原则
            while (low <= high) {
                int mid = (low + high) >>> 1;
                int midValue = array[mid];
                if (key < midValue) {
                    high = mid - 1;
                } else if (key > midValue) {
                    low = mid + 1;
                } else {
                    return mid;
                }
            }
            return -(low + 1);
        }
    

    快速排序

    应用场景:数据量大并且是线性排序。
    注意:不要在链式结构中使用,重复数据过多也不合适

    /**
         * 快速排序
         *
         * @param array
         * @param begin
         * @param end
         */
        private static void quickSort(int[] array, int begin, int end) {
            if (end - begin <= 1) {
                return;
            }
            int x = array[begin];//暂存枢纽
            int low = begin;
            int high = end;
            boolean direction = true;//排序方向  true:为从右往左  false:从左往右
            L1:
            while (low < high) {
                if (direction) {//从右往左
                    for (int i = high; i > low; i--) {
                        if (array[i] <=x) {
                            array[low++] = array[i];
                            high = i;
                            direction = !direction;//切换方向
                            continue L1;
                        }
                    }
                    high = low;
                } else {
                    for (int i = low; i < high; i++) {
                        if (array[i] >= x) {
                            array[high--] = array[i];
                            low = i;
                            direction = !direction;
                            continue L1;
                        }
                    }
                    low = high;
                }
    
            }
            //把最后找到的值放入中间位置
            array[low] = x;
    
            //开始完成左右两边的操作 二叉树的前序遍历
            quickSort(array, begin, low - 1);
            quickSort(array, begin + 1, end);
    
        }
    

    输出结果:
    31 68 45 90 23 39 54 12 87 76
    12 23 31 39 45 54 68 76 87 90

    归并排序

    解决快排不能操作单链表的问题,但是空间牺牲大

     /**
         * 归并排序
         *
         * @param array
         * @param left
         * @param right
         */
        public static void mergeSort(int[] array, int left, int right) {
            if (left == right) {
                return;
            } else {
                int mid = (left + right) / 2;
                mergeSort(array, left, mid);//排好左边
                mergeSort(array, mid + 1, right);//排好右边
                merge(array, left, mid + 1, right);//再对左右进行合并
            }
        }
    
    
        /**
         * 通过拆分数组合并数据来对数据排序
         *
         * @param array
         * @param left
         * @param mid
         * @param right
         */
        public static void merge(int[] array, int left, int mid, int right) {
            int leftSize = mid - left;
            int rightSize = right - mid + 1;
    
            //开始生产数组
            int[] leftArray = new int[leftSize];
            int[] rightArray = new int[rightSize];
            // 填充左边数组
            for (int i = left; i < mid; i++) {
                leftArray[i - left] = array[i];
            }
    
            //填充右边数组
            for (int i = mid; i <= right; i++) {
                rightArray[i - mid] = array[i];
            }
    
    
            //合并数组
            int i = 0;
            int j = 0;
            int k = left;
    
            while (i < leftSize && j < rightSize) {
                if (leftArray[i] < rightArray[j]) {
                    array[k++] = leftArray[i++];
                } else {
                    array[k++] = rightArray[j++];
                }
            }
            //表示左边还有数据没有合并完
            while (i < leftSize) {
                array[k++] = leftArray[i++];
            }
    
            //表示右边边还有数据没有合并完
            while (j < rightSize) {
                array[k++] = rightArray[j++];
            }
    
        }
    

    插入

    直接插入排序

    在已经有序的数据中,插入一个数据,使用插入排序效率是非常高的。比如纸牌和麻将

     /**
         * 直接插入排序
         * @param array
         */
        public static void insertSort(int[] array){
            for (int i = 1; i < array.length; i++) {
                int  j =i;
                int target =array[i];
                while (j>0 &&target<array[j-1]){
                    array[j]=array[j-1];
                    j--;
                }
                array[j]=target;
    
            }
        }
    
    

    希尔排序

    对插入排序进行优化,增加了一个步长

    /**
         * 希尔排序
         *
         * @param array
         * @param step  步长
         */
        public static void shellSort(int[] array, int step) {
            for (int k = 0; k < step; k++) {//k 是对步长的一个定位,选择每次操作的开始位置
                for (int i = k + step; i < array.length; i = i + step) {
                    int j = i;
                    int target = array[i];
                    while (j > step - 1 && target < array[j - step]) {
                        array[j] = array[j - step];
                        j=j-step;
                    }
                    array[j] = target;
                }
            }
        }
    

    相关文章

      网友评论

          本文标题:排序

          本文链接:https://www.haomeiwen.com/subject/cnhtlftx.html