6种排序算法的工具类

import java.util.ArrayList;

/** * Created by Cronous on 2018/5/24. * 该类主要用于对排序算法做一个整理,自己造轮子 * 包括以下6种排序算法 * 1.直接插入排序 directInsertSort(int[] inputArr) * 2.希尔排序(插入排序的增量版)shellInsertSort(int[] inputArr) * 3.冒泡排序 bubbleSort(int[] inputArr) * 4.快速排序 quickSort(int[] inputArr,int left,int right) * 5.选择排序(直接选择)straightSelectSort(int[] inputArr) * 6.堆排序 stackSort(int[] inputArr) */
public class Sorted {

    /** * 直接插入排序 * @param inputArr 待插入排序的数组 */
    public static void directInsertSort( int[] inputArr){

        //原数组的长度,方便计算循环次数
        int count = inputArr.length;

        for( int i = 1;i < count;i++){
            for( int j = i;j > 0 && inputArr[j] < inputArr[j - 1];j--){
                int temp = inputArr[j];
                inputArr[j] = inputArr[j - 1];
                inputArr[j - 1] = temp;
            }
        }
    }

    /** * 希尔插入排序(缩小增量排序)这里我选用的是 {n/2,[n/2]/2,....,1}增量来进行 * @param inputArr 待排序数组 */
    public static void shellInsertSort( int[] inputArr){
        //希尔排序的增量选择,这里我们使用 {n/2,[n/2]/2,....,1}来进行,希尔排序的增量选择是不确定的
        int count = inputArr.length;
        //初始 gap
        int gap = count / 2;
        while(gap >= 1){

            //1.先通过gap来进行分组,分组个数 = gap
            int arrCount = gap;
            //2.再次循环,分出一个数组就排序,排序完就放回去,这里我们创建一个list来进行存储,
            // 因为我们不知道最后的分组有多少个元素,再创建一个list来进行下标的存储,方便我回写回去

            for( int i = 0;i < arrCount;i++){
                ArrayList elemList = new ArrayList();
                ArrayList indexList = new ArrayList();
                for( int j = 0;j < count;){
                    elemList.add(inputArr[j]);
                    indexList.add(j);
                    j = j + gap; //设置循环条件
                }
                //3.在这里进行插入排序,然后回写,这里我们调用前面写好的插入排序,要求变换一些格式,是个int[]数组
                int[] tmp = new int[elemList.size()];
                for( int s = 0;s < elemList.size();s++){
                    tmp[s] = ( int) elemList.get(s);
                }
                //4.插入排序
                directInsertSort(tmp);
                //5.回写
                for( int v = 0;v < indexList.size();v++){
                    int index = ( int) indexList.get(v);
                    inputArr[index] = tmp[v];
                }
            }
            gap = gap / 2;
        }
    }

    /** * 冒泡排序 * @param inputArr 待排序数组 */
    public static void bubbleSort( int[] inputArr){

        /* 设数组的长度为 N: (1)比较前后相邻的二个数据,如果前面数据大于后面的数据,就将这二个数据交换。 (2)这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就“沉”到数组第N-1个位置。 (3)N=N-1,如果N不为0就重复前面二步,否则排序完成。 这里特别注意与选择排序的的区别,这里是两辆交换,选择排序是每次遍历找出最小的元素加入新数组 */
        for( int i = 0;i < inputArr.length;i++){
            for( int j = 0;j < (inputArr.length - 1) - i;j++){
                if(inputArr[j + 1] < inputArr[j]){
                    int temp = inputArr[j + 1];
                    inputArr[j + 1] = inputArr[j];
                    inputArr[j] = temp;
                }
            }
        }
    }


    /** * 快速排序 * @param inputArr 待排序数组 * @param left 数组开始下标 * @param right 数组结束下标 */
    public static void quickSort( int[] inputArr, int left, int right){
        /** * * 1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。 * 2.j–-由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。 * 3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。 * 4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。 * 具体例子可以在网上查找一下 */
        if (left < right) {
            int i = left, j = right, x = inputArr[left];
            while (i < j) {
                while(i < j && inputArr[j] >= x){
                    j--;
                } // 从右向左找第一个小于x的数

                if(i < j){
                    inputArr[i++] = inputArr[j];
                }
                while(i < j && inputArr[i] < x){
                    i++;
                } // 从左向右找第一个大于等于x的数

                if(i < j){
                    inputArr[j--] = inputArr[i];
                }
            }
            inputArr[i] = x;
            quickSort(inputArr, left, i - 1); // 递归调用
            quickSort(inputArr, i + 1, right);
        }
    }

    /** * 直接选择排序 * @param inputArr 待排序数组 */
    public static void straightSelectSort( int[] inputArr){
        /** * 首先在所有记录中选出关键字值最小的记录, * 把它与第一个记录进行位置交换,然后在其余的记录中再选出关键字值次小的记录与第二个记录进行位置交换, * 依此类推,直到所有记录排好序。 */
        for( int i = 0;i < inputArr.length;i++){
            //这个循环用来存放除了除了排好的最小值剩下的数组
            int[] tempArr = new int[inputArr.length - i];
            for( int j = i;j < inputArr.length;j++){
                tempArr[j - i] = inputArr[j];
            }

            int[] ret = getMin(tempArr);
            int index = ret[ 0];
            int min = ret[ 1];
            //交换
            int temp = inputArr[i];
            inputArr[i] = inputArr[index + i]; //这里加 i 是因为取后面数组每次长度都减 1,将下标还原
            inputArr[index + i] = temp;
        }
    }

    /** * 堆排序 * @param inputArr 待排序数组 */
    public static void stackSort( int[] inputArr){
        //1.构建大顶堆
        for( int i = inputArr.length / 2 - 1;i >= 0;i--){
            //从第一个非叶子结点从下至上,从右至左调整结构
            adjustHeap(inputArr,i,inputArr.length);
        }
        //2.调整堆结构+交换堆顶元素与末尾元素
        for( int j = inputArr.length - 1;j > 0;j--){
            swap(inputArr, 0,j); //将堆顶元素与末尾元素进行交换
            adjustHeap(inputArr, 0,j); //重新对堆进行调整
        }
    }

    /** * 调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上) * @param inputArr * @param i * @param length */
    public static void adjustHeap( int[] inputArr, int i, int length){
        int temp = inputArr[i]; //先取出当前元素i
        for( int k = i * 2 + 1;k < length;k = k * 2 + 1){ //从i结点的左子结点开始,也就是2i+1处开始
            if(k + 1 < length && inputArr[k] < inputArr[k + 1]){ //如果左子结点小于右子结点,k指向右子结点
                k++;
            }
            if(inputArr[k] > temp){ //如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
                inputArr[i] = inputArr[k];
                i = k;
            } else{
                break;
            }
        }
        inputArr[i] = temp; //将temp值放到最终的位置
    }
    /** * 交换函数 * @param a 将需要交换的数封装为数组长度为 2的数组形式 */
    public static void swap( int[] a){
        int temp = a[ 0];
        a[ 0] = a[ 1];
        a[ 1] = temp;
    }

    /** * 交换元素 * @param arr * @param a * @param b */
    public static void swap( int []arr, int a , int b){
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }

    /** *求int数组当中最小值 * @param arr 待求数组 * @return 返回值 int[] 数组,第一项为最小值的下标,第二项为最小值 */
    public static int[] getMin( int[] arr){
        int[] ret = new int[ 2];
        int min = arr[ 0];
        for( int i = 0;i < arr.length;i++){
            if(arr[i] < min){
                min = arr[i];
                ret[ 0] = i;
            }
            ret[ 1] = min;
        }
        return ret;
    }

    public static void main(String[] args){

        int[] input = new int[]{ 5, 2, 1, 9, 8};
        //directInsertSort(input);
        //shellInsertSort(input);
        //bubbleSort(input);
        //quickSort(input,0,4);
        //straightSelectSort(input);
        stackSort(input);
        for ( int x: input) {
            System.out.print(x+ ",");
        }
    }
}
  • 1

猜你喜欢

转载自blog.csdn.net/qq_22060403/article/details/80484838