zoukankan      html  css  js  c++  java
  • java冒泡,选择,插入,希尔,归并,快速排序算法

    import java.lang.reflect.Array;
    import java.util.Arrays;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    public class BasicSortDemo {
        public static void main(String[] args) {
    
            int[] arr = {20, 33, 5, 45, 56, 6, 7, 9, 58, 4, 34, 34, 332, 8, 43, 74, 52};//Stream.of().collect(Collectors.toList()).toArray();
    //        int[] arr = {3, 4, 2, 5, 1};//Stream.of().collect(Collectors.toList()).toArray();
    //        BubbleSort(arr);
    //        selectSort(arr);
    //        insertSort(arr);
    //        shellSort(arr);
    //        insertSort_front2back(arr);
    //        shellSort(arr);
    //        mergeSort(arr);
            speedsort(arr);
            printArray(arr);
    
        }
    
        static void BubbleSort(int[] arr) {
            for (int i = 0; i < arr.length; i++) {
                for (int j = i + 1; j < arr.length; j++) {
                    if (arr[i] > arr[j]) {
                        swap(arr, i, j);
                    }
                }
            }
        }
    
        //选择排序,每次都取最小的放在已排序数组后面
        static void selectSort(int[] arr) {
            for (int i = 0; i < arr.length; i++) {
                int current = arr[i];
                int minIndex = i;
    
                for (int j = i + 1; j < arr.length; j++) {
                    if (arr[j] < current) {
                        minIndex = j;
                        current = arr[j];
                    }
                }
                //找到更小的,交换位置
                if (minIndex > i) {
                    swap(arr, i, minIndex);
                }
            }
        }
    
        //插入排序,对于未排序的,每次取出一个之后向前移动,直到找到比自己小的为止.插入
        static void insertSort_back2front(int[] arr) {
            for (int i = 0; i < arr.length - 1; i++) {
                int nSortedIndex = i + 1;
                while (nSortedIndex > 0 && arr[nSortedIndex] < arr[nSortedIndex - 1]) {
                    swap(arr, nSortedIndex - 1, nSortedIndex);
                    nSortedIndex--;
                }
            }
        }
    
        //从后向前, 每个值都遍历一次,并且都向前查找位置
        static void insertSort_front2back(int[] arr) {
    
            for (int i = 0; i < arr.length; i++) {
                int nCurrent = arr[i];
                int npre = i - 1;
                while (npre >= 0 && arr[npre] > nCurrent) {
                    arr[npre + 1] = arr[npre];
                    npre--;
                }
                arr[npre + 1] = nCurrent;
            }
    
        }
    
        //希尔排序,简单插入排序的改进版,它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。
        static void shellSort(int[] arr) {
            int nStartGap = ((Double) (Math.floor((arr.length / 2)))).intValue();
            for (int nStep = nStartGap; nStep > 0; nStep = nStep / 2) {
                //里面是隔着step个数的插入排序
                for (int i = nStep; i < arr.length; i++) {
    
                    int nCurrent = arr[i];
                    int nPre = i - nStep;
                    //向前找位置
                    while (nPre >= 0 && nCurrent < arr[nPre]) {
                        arr[nPre + nStep] = arr[nPre];
                        nPre = nPre - nStep;
                    }
                    arr[nPre + nStep] = nCurrent;
                }
            }
        }
    
        //#region 归并算法, 将数据一直拆分到每个数组只有一个元素, 然后再逐个合并数组
    
        static void mergeSort(int[] arr) {
    
            int[] res = doMergeSort(arr);
            for (int i = 0; i < arr.length; i++) {
                arr[i] = res[i];
            }
        }
    
        static int[] doMergeSort(int[] arr) {
    
            if (arr.length < 2) {
                return arr;
            }
            int middle = ((Double) Math.floor(arr.length / 2)).intValue();
            int[] left = Arrays.copyOfRange(arr, 0, middle);
            int[] right = Arrays.copyOfRange(arr, middle, arr.length);
    
    //        int[] arrT = mergeArray(doMergeSort(left), doMergeSort(right));
            int[] arrT = mergeArray_2(doMergeSort(left), doMergeSort(right));
    
            return arrT;
        }
    
        static int[] mergeArray_2(int[] left, int[] right) {
    
            System.out.println("");
            System.out.println("left");
            printArray(left);
            System.out.println("right");
            printArray(right);
    
    
            int i = 0, j = 0, t = 0;
    
            int[] res = new int[left.length + right.length];
    
            while (i < left.length && j < right.length) {
                if (left[i] <= right[j]) {
                    res[t++] = left[i++];
                } else {
                    res[t++] = right[j++];
                }
            }
    
            if (i >= left.length) {
                while (j < right.length) {
                    res[t++] = right[j++];
                }
            }
    
            if (j >= right.length) {
                while (i < left.length) {
                    res[t++] = left[i++];
                }
            }
            printArray(res);
            System.out.println("=====doen ====");
            return res;
        }
    
        static int[] mergeArray(int[] left, int[] right) {
    
            System.out.println("left");
            printArray(left);
            System.out.println("right");
            printArray(right);
            System.out.println("=========");
            int[] res = new int[left.length + right.length];
    
            int t = 0;
            int nRIghtFlag = 0;
            for (int i = 0; i < left.length; i++) {
                int nLeft = left[i];
    
                boolean nLeftUsed = false;
                for (int j = nRIghtFlag; j < right.length; j++) {
                    if (nLeft <= right[j]) {
                        res[t++] = nLeft;
                        nLeftUsed = true;
                        break;
                    } else {
                        res[t++] = right[j];
                        nRIghtFlag++;
                    }
                }
    
                if (!nLeftUsed) {
                    res[t++] = nLeft;
                }
            }
            if (nRIghtFlag < right.length) {
                for (int i = nRIghtFlag; i < right.length; i++) {
                    res[t++] = right[i];
                }
            }
    
            printArray(res);
            return res;
        }
    
    
        //endregion
    
        static void speedsort(int[] arr) {
            speedSort_1(arr, 0, arr.length - 1);
        }
    
        static void speedSort_1(int[] arr, int start, int nend) {
    
            if (nend > start) {
    //            int nMiddle = speedSortPartioner(arr, start, nend);
    //            int nMiddle = speedSortPartioner_2(arr, start, nend);
                int nMiddle = speedSortPartioner_3(arr, start, nend);
                speedSort_1(arr, start, nMiddle);
                speedSort_1(arr, nMiddle + 1, nend);
                System.out.println(nMiddle);
            }
        }
    
    
        //方式一:
        //因为base为左边第一个元素, 所有遍历时先从右边开始,从右边找到第一个小于base的值,然后复制到左边low位置(覆盖第一个low也就是base位置)
        //然后从左边寻找第一个大于base的值,找到后移动到右边high位置(该位置为原来小于base的值),
        //如此往复,知道low不在前进了为止,此时使用base值覆盖low位置的值,完成第一次排序(小于base的都在前面,大于base的都在后面)
        static int speedSortPartioner(int[] arr, int low, int high) {
            int nBase = arr[low];
            while (low < high) {
                while (low < high && arr[high] >= nBase) {
                    high--;
                }
                arr[low] = arr[high];
    
                //从左向右,知道找打大于base的数据
                while (low < high && arr[low] <= nBase) {
                    low++;
                }
                arr[high] = arr[low];
            }
    
            arr[low] = nBase;
    
            System.out.println("low result " + low);
            printArray(arr);
            System.out.println("   ");
            System.out.println("done ");
            return low;
        }
    
        //
        //定义index变量,记录小于base的位置.起始位置为low
        //1.定义pointer指针从low追个遍历到high
        //2.如果pointer所指向位置小于base,则与index位置互换,index++
        //(备注index-1位置肯定是最后一个小于base值的位置)
        //3.如此遍历整个low-high所有元素
        //4.遍历结束后,互换low与index-1元素,这样保证所有小于base的值在左边,大于base的值在右边
    
        static int speedSortPartioner_3(int[] arr, int low, int high) {
    
            int pointer = low + 1, j = high;
            int index = pointer, nBase = arr[low];
    
    //从low+1开始替换,最后low要与index替换
            while (pointer <= j) {
                if (arr[pointer] < nBase) {
                    swap(arr, index, pointer);
                    index++;
                }
                pointer++;
            }
            swap(arr, low, index - 1);
            return index - 1;
    
        }
    
        //快速排序方式二
        //base值这里默认为数组第一个元素.
        //1.从右边找到第一个小于base的值,从左边找到第一个大于base的值
        //2.交换low,high位置(注意是互换的两个元素分别是大于和小于base的值)
        //3.回到1,分别从右边和左边找到匹配的值,然后互换位置
        //4.如果low位置不再变化,此时low和high可能指向同一个元素或者相邻的元素
        //5.替换low位置与base的值,这样保证互换过的小于base的值都在前面,大于base的值都在后面
        //6.完成了一次排序
        static int speedSortPartioner_2(int[] arr, int low, int high) {
            int nLeftIndex = low;
            int nBase = arr[low];
    
            while (low < high) {
                //找到右边第一个小的
                while (low < high && arr[high] >= nBase) {
                    high--;
                }
    
                //找到左边第一个大的
                while (low < high && arr[low] <= nBase) {
                    low++;
                }
    
                if (low < high) {
                    swap(arr, low, high);
                }
            }
            //将base上的基数与low位置替换,不管low,high是否指向同一值,因为可以判断low位置一定小于base
    
            swap(arr, low, nLeftIndex);
    
            System.out.println("low result " + low);
            printArray(arr);
            System.out.println("done  ");
            System.out.println("   ");
            return low;
        }
    
        static void selectSort_2(int[] arr) {
        }
    
        static void printArray(int[] arr) {
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i]);
                System.out.print(" ");
            }
            System.out.println("");
        }
    
        static void swap(int[] arr, int from, int to) {
            int tmp = arr[to];
            arr[to] = arr[from];
            arr[from] = tmp;
        }
    }
  • 相关阅读:
    unittest详解(二) 跳过用例的执行(skip)
    Selenium获取input值的两种方法:WebElement.getAttribute("value")和WebElement.getText()
    python 函数参数的传递(参数带星号的说明) 元组传递 字典传递
    获取当前运行函数名称和类方法名称
    python中datetime模块中strftime/strptime函数
    面试题
    H5测试-缓存机制
    cp命令
    Java面试
    名词解释。。
  • 原文地址:https://www.cnblogs.com/snow-man/p/14489636.html
Copyright © 2011-2022 走看看