八大排序算法归纳

news2024/12/23 0:11:51

1、排序

排序:所谓排序就是使一连串记录,按照其中某个或某个关键字的大小,递增或递减的排列起来的操作。

稳定性:假定在待排序记录序列中存在有多个具有相同关键字的记录,若经过排序这些记录的相对次序保持不变,即原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍然在r[j]之前,则称这种算法是稳定的;否则不稳定

内部排序:数据元素全部放在内存中的排序

外部排序:数据元素太多不能同时放在内存中,根据排序过程要求不能在内外存之间移动数据的排序

以下是常见排序算法的实现

2、插入排序

*基本思想:直接插入排序是一种简单的插入排序,其基本思想是,把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列

(1)首先看第一个数,将数组划分为有序和无序,-----首先看第一个数2,一个数必然有序,所以将2划分为有序,后面都是无序

 (2)无序部分的首个插入到有序部分,-----取出无序部分的首个,在有序部分从后向前进行比较,插入到合适位置

 (3)重复第二部直到无序部分去拿不插入有序序列,-----8也是依次比较就可以插入

 3就需要多次比较,注意是多次比较,直接插入,不是比较一次就插入一次(与冒泡不同)

*首先要有两个元素去比较,让i=1,j=i-1;

*记录i下标的值

*j下标的值与temp去比较,如果j下标的值比temp大,把j下标的值移动到j+1位置 j--

*最后把temp放在j+1的位置

 2.1、直接插入排序特性总结:

*元素集合越接近有序,直接插入排序算法的时间效率越高

*时间复杂度:O(n^2)

*空间复杂度:O(1)

稳定性:稳定

 /**
     * 插入排序
     * 时间复杂度O(n^2),已经有序的情况下为O(n)
     * 空间复杂度O(1)
     * 稳定性:稳定
     * @param array
     */
    public static void insertSort(int[] array){
        for (int i = 0; i < array.length; i++) {
            //保存i下标的值
            int temp=array[i];
            //指定j下标为i-1
            int j=i-1;
            //一直遍历到数组开头
            while(j>=0){
                //比较i和j位置的值,如果j下标的值小于i下标的值,说明有序
                if(array[j]<=array[i]){
                    break;
                }
                //移动j的值到j+1
                array[j+1]=array[i];
                j--;
            }
            //把temp的值放到j+1
            array[j+1]=temp;
        }
    }
    //测试插入排序运行时间
    public static void TestInsertSort(int[] array){
        //记录开始时间
        long begin=System.currentTimeMillis();
        insertSort(array);
        //记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("插入排序耗时--->"+(end-begin));
    }

3、希尔排序:

希尔排序又称缩小增量法。希尔排序的基本思想是:把记录下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量的逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件就恰好分成一组,算法终止

 

 

 3.1、希尔排序算法特性总结

*希尔排序是对直接插入排序算法的优化

*当gap!=1时都是预排序,目的是让数组更接近于有序。当gap=1时,数组已经接近有序了,这样就会很快。这样整体而言就会达到优化的效果

*希尔排序的时间复杂度不好计算,因为gap的取值方法有很多,导致很难去计算,因此希尔排序的时间复杂度都不固定

*稳定性:不稳定

/**
     * 希尔排序
     * 时间复杂度:O(N^1.25)~O(N^1.5)
     * 稳定性:不稳定
     * 空间复杂度O(1)
     * @param array
     */
    public static void shellSort(int[] array){
        //1、确定gap的值
        int gap=array.length;
        //2、开始循环
        while(gap>0){
            shell(array,gap);
            gap/=2;
        }
    }

    private static void shell(int[] array, int gap) {
        //从gap位置进行遍历
        for (int i = gap; i <array.length ; i++) {
            //用temp保存i的值
            int temp=array[i];
            //内层循环之前,先定义j的值
            int j=i-gap;
            //开始循环
            while(j>=0){
                //比较j和i的值
                if(array[j]<=array[i]){
                    break;
                }
                //移动j的值到j+gap
                array[j+gap]=array[j];
                j-=gap;
            }
            //最后将temp放到对应位置
            array[j+gap]=temp;
        }
    }
    //测试插入排序运行时间
    public static void TestShellSort(int[] array){
        //记录开始时间
        long begin=System.currentTimeMillis();
        shellSort(array);
        //记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("希尔排序耗时--->"+(end-begin));
    }

4、选择排序

每一次从待排序的数据元素中选取最小的或最大的一个元素,,存放在序列的其实位置,直到全部待排序的数据元素排完

 4.1、直接选择排序的特性总结

*直接选择排序非常好理解,但是效率不是很高,实际中应用很少

*时间负责度O(n^2)

*空间复杂度O(1)

*稳定性:不稳定

/**
     * 直接选择排序1
     * 时间复杂度:O(n^2)
     * 空间复杂度O(1)
     * 稳定性:不稳定
     * @param array
     */
    public static void selectSort1(int[] array){
        //1、从0下标开始往后遍历
        for (int i = 0; i < array.length; i++) {
            //2、记录最小值下标,默认最小值下标是i
            int minIndex=i;
            //3、从i+1下标开始往后遍历
            for (int j = i+1; j < array.length; j++) {
                //4、如果还能够找到比minIndex还小的值,更新下标
                if(array[j]<array[minIndex]){
                    minIndex=j;
                }
            }
            //5、交换minIndex和i的元素
            swap(array,minIndex,i);
        }
    }
    //交换数组元素
    private static void swap(int[] array, int minIndex, int i) {
        int temp=array[minIndex];
        array[minIndex]=array[i];
        array[i]=temp;
    }
    //测试直接选择排序1运行时间
    public static void TestSelectSort1(int[] array){
        //记录开始时间
        long begin=System.currentTimeMillis();
        selectSort1(array);
        //记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("直接选择排序1耗时--->"+(end-begin));
    }

4.2算法优化-一次遍历同时找到最大值和最小值

 

/**
     * 直接选择排序2
     * 时间复杂度:O(n^2)
     * 空间复杂度:O(1)
     * 稳定性:不稳定
     * @param array
     */
    public static void selectSort2(int[] array){
        //1、定义数组边界
        int left=0;
        int right=array.length-1;
        //进入循环
        while(left<right){
            //2、定义最小值和最大值下标
            int minIndex=left;
            int maxIndex=left;
            for (int i = left+1; i <right; i++) {
                //3、如果i下标的值比最小值下标的值还小,那么更新最小值下标
                if(array[i]<array[minIndex]){
                    minIndex=i;
                }
                //4、如果i下标的值比最大值下标的值还大,那么更新最大值下标
                if(array[i]>array[maxIndex]){
                    maxIndex=i;
                }
            }
            //5、每次遍历完之后,left和minIndex交换
            if(left!=minIndex){
                swap(array,left,minIndex);
            }
            //6、修正最小值和最大值重复交换的问题
            if(left==maxIndex){
                maxIndex=minIndex;
            }
            //7、right和maxIndex交换
            if(right!=maxIndex){
                swap(array,right,maxIndex);
            }
            //8、移动left和right
            left++;
            right--;
        }
    }
    //测试直接选择排序2运行时间
    public static void TestSelectSort2(int[] array){
        //记录开始时间
        long begin=System.currentTimeMillis();
        selectSort2(array);
        //记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("直接选择排序2耗时--->"+(end-begin));
    }

5、堆排序

堆排序是指利用堆这种数据结构所设计的一种排序算法,它是选择排序的一种,它是通过堆来进行选择数据。排升序要建大堆,排降序要建小堆

(1)根据数组创建堆

(2)按照删除元素的逻辑,第一个下标的元素最后一个下标的元素交接

(3)从根节点向下调整这棵二叉树

(4)从后一个节点一调排序到根节点

 

/**
     * 堆排序
     * 时间复杂度:O(nlog(n))
     * 空间复杂度:O(1)
     * 稳定性:不稳定
     * @param array
     */
    public static void HeapSort(int[] array){
        //1、首先要建一个堆
        creatHeap(array);
        //2、确定终止下标
        int end=array.length;
        while(end>=0){
            //3、首尾交换
            swap(array,0,array.length-1);
            //4、向下调整
            shiftDown(array,0,end);
            //5、修正end的值
            end--;
        }
    }

    private static void shiftDown(int[] array, int parent, int length) {
        //定义左孩子节点
        int child=2*parent+1;
        //循环处理,判断是否越界
        while(child<parent){
            //判断是否有右孩子节点
            if(child+1<length){
                //判断左右孩子的大小,右孩子节点大,就选右孩子节点下标
                if(array[child]<array[child+1]){
                    child++;
                }
            }
            //孩子节点与父节点进行比较
            if(array[child]<=array[parent]){
                break;
            }
            //交换父子下标值
            swap(array,parent,child);
            //重置父子节点下标
            parent=child;
            child=2*parent+1;
        }
    }

    /**
     * 建堆
     * @param array
     */
    private static void creatHeap(int[] array) {
        //找到最后一个不为0的节点
        for (int parent = (array.length-2)/2; parent>=0 ; parent--) {
            shiftDown(array,parent,array.length);
        }
    }
    //测试堆排序运行时间
    public static void TestHeapSort(int[] array){
        //记录开始时间
        long begin=System.currentTimeMillis();
        HeapSort(array);
        //记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("堆排序耗时--->"+(end-begin));
    }

6、冒泡排序

重复扫描待排序序列,并比较每一对相邻的元素,当该队元素顺序不正确时的进行交换。一直重复这个过程,直到没有任何两个元素可以交换,叫表明完成了排序

 6.1、冒泡排序特性总结:

*冒泡排序是一种非常容易理解的排序

*时间复杂度:O(N^2)

*空间复杂度:O(1)

*稳定性:稳定

/**
     * 冒泡排序
     * 时间复杂度:O(n^2)
     * 空间复杂度:O(1)
     * 稳定性:稳定
     * @param array
     */
    public static void bubbleSort(int[] array){
        for (int i = 0; i < array.length-1; i++) {
            boolean flag=false;
            for (int j = i; j <array.length-1 ; j++) {
                if(array[j]>=array[j+1]){
                    swap(array,j,j+1);
                    //如果交换了数组元素下标,flag置反
                    flag=true;
                }
            }
            //没有参与比较,说明已经有序了
            if(!flag){
                break;
            }
        }
    }
    //测试堆排序运行时间
    public static void TestBubbleSort(int[] array){
        //记录开始时间
        long begin=System.currentTimeMillis();
        bubbleSort(array);
        //记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("冒泡排序耗时--->"+(end-begin));
    }

7、快速排序

任取待排序序列中的某元素作为基准值,按照该排序码将待排序序列集合分割成两个子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后左右子序列重复该过程,直到所有元素都排列到相应的位置

(1)它是一个运用了二叉树结构进行的一排序,那么就要分割左右区段

(2)要有一个基准值,这个基准值左边都是小于这个值的元素,右边都是大于这个值的元素

重点;如何去找这个基准值

*首先让left=0,right=array.length-1

*以left下标的值为默认基准值

*right向左移动,找到比基准值小的停下来

*left向右移动,找到比基准值大的停下来

*left与right交换

*当left与right相遇的时候,让提前记录好的基准与相遇点进行交换

*返回相遇点的下标,这个下标就是基准
 


    /**
     * 快速排序
     * 时间复杂度:O(N*logN)
     * 空间复杂度:O(logN)
     * 稳定性:不稳定
     * @param array
     */
    public static void quickSort(int[] array){
        quickProcessSort(array,0,array.length-1);
    }

    private static void quickProcessSort(int[] array, int left, int right) {
        //1、终止条件
        if(left<right){
            return;
        }
        //============用插入法优化树的倒数低N层===============
        if(right-left<5){
            InsertSort(array,left,right);
            return;
        }
        //=============三数取中法优化栈溢出问题===============
        int middle=middleValue(array,left,right);
        //与left交换
        swap(array,left,middle);
        //2、在区段中找基准
        int point=partitionHoare(array,left,right);//Hoare找基准
        //int point=partitionHole(array,left,right);//挖坑法找基准
        //int point= partitionPoint(array,left,right);//快慢指针法
        //3、根据基准处理左区段跟右区段
        quickProcessSort(array ,left,point-1);
        quickProcessSort(array,point+1,right);
    }
    //测试快速排序运行时间
    public static void TestQuickSort(int[] array){
        //记录开始时间
        long begin=System.currentTimeMillis();
        quickSort(array);
        //记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("快速排序耗时--->"+(end-begin));
    }

7.1、挖坑法找基准

*left下标的值当作基准值,这时left的位置就空出来了

*right向左移动,找到比基准值还要小的值,放到left位置

*left向右移动,找到比基准值还要大的值,放到right位置

*当left和right相遇时,把之前记录的基准值放到相遇的下标

*返回相遇点下标,这就是基准的下标

private static int partitionHole(int[] array, int left, int right) {
        //默认基准值下标为left
        int pointValue=array[left];
        //left和right不相遇循环
        while(left<right){
            //从右边找比基准值更小的
            if(left<right&&array[right]>=pointValue){
                //right向左移
                right--;
            }
            //把right下标放到left下标上面
            array[left]=array[right];
            //从左边找比基准值更大的
            if(left<right&&array[left]<=pointValue){
                //left右移
                left++;
            }
            //把left下标放到right下标上面
            array[right]=array[left];
        }
        //当left和right下标相遇时,将基准值放到相遇点
        array[left]=pointValue;
        //返回基准值
        return left;
    }

7.2、快慢指针法找基准

 

 /**
     * 快慢指针法找基准值
     * @param array
     * @param left
     * @param right
     * @return
     */
    private static int partitionPoint(int[] array, int left, int right) {
        //定义两个变量
        int prev=left;
        int current=left+1;
        while(current<right){
            //current下标的值小于基准值
            if(array[current]<array[left]){
                prev++;
                if(array[current]!=array[prev]){
                    swap(array,current,prev);
                }
            }
            //current向后移动
            current++;
        }
        //遍历完成之后,prev与基准下标交换
        swap(array,left,prev);
        //返回prev下标
        return prev;
    }

7.3、Hoare法找基准

  /**
     * Hoare找基准值
     * @param array
     * @param left
     * @param right
     * @return
     */
    private static int partitionHoare(int[] array, int left, int right) {
        //1、默认left为基准值
        int pointValue=array[left];
        //2、记录基准值的下标
        int pointIndex=left;
        //left和right不相遇时进行循环处理
        while(left<right){
            //让right向右移动,找到比right小的停下来,注:必须先右移而不能先左移
            while(left<right&&array[right]>=pointValue){
                //移动right下标
                right--;
            }
            //让left向左移动,找到比left大的停下来,注:等号不能省略
            while(left<right&&array[left]<=pointValue){
                //移动left下标
                left++;
            }
            //交换left和right的值
            swap(array,left,right);
        }
        //更新基准值为相遇值
        swap(array,left,pointIndex);
        //返回相遇点的下标
        return left;
    }

7.4、解决栈溢出问题-三数取中法

*以数组最左边和最右边的值作为基准

*根据最左边和最右边的下标,找到数组中间的下标

*以左下标、中间下标和右下标对应的值,在这三个值中找到中间大小的那个值

/**
     * 三数取中法
     * 解决快速排序中栈溢出问题
     * @param array
     * @param left
     * @param right
     * @return
     */
    private static int middleValue(int[] array, int left, int right) {
        //找出数组中间下标
        int mid=(left+right)/2;
        //开始处理核心逻辑
        if(array[left]<array[right]){
            //left下标值小于right下标值
            if(array[mid]<array[left]){
                //中间的值比最小的还要小,返回left
                return left;
            }else if(array[mid]>array[right]){
                //中间的值比最大的还要大,返回right
                return right;
            }else{
                //中间值在left和right中间,返回mid
                return mid;
            }
        }else{
            //left下标值大于right下标值
            if(array[mid]>array[left]){
                //中间值比最大的还要大,返回left
                return left;
            }else if(array[mid]<array[right]){
                //中间值比最小的还要小,返回right
                return right;
            }else{
                //中间值在left和right中间,返回mid
                return mid;
            }
        }
    }

7.5、用插入法优化树的倒数低N层

/**
     * 针对数组的某一个区段,插入排序
     * @param array
     * @param left
     * @param right
     */
    private static void InsertSort(int[] array, int left, int right) {
        for (int i = left+1; i <right ; i++) {
            //保存i的值
            int temp=array[i];
            //内层循环,先指定j的下标为i-1
            int j=i-1;
            //一直遍历到数组开头
            while(i>left){
                //如果i下标的值小于temp,说明前面都有序
                if(array[i]<temp){
                    break;
                }
                //移动j的值到j+1位置
                array[j+1]=array[j];
                i--;
            }
            //把temp的值放到i+1位置
            array[i+1]=temp;
        }
    }

8、快速排序--迭代

/**
     * 快速排序迭代法
     * 迭代的方式,快速排序
     * @param array
     */
    public static void quickSort2(int[] array){
        quickProcessSort2(array,0,array.length-1);
    }

    private static void quickProcessSort2(int[] array, int left, int right) {
        //1、定义一个栈用来记录左右区段的左右下标值
        Stack<Integer> stack=new Stack<>();
        //===========2、用插入排序优化,树的倒数N层开始===========
        if(right-left+1<=5){
            swap(array,left,right);
            return;
        }
        //===========用插入排序优化,树的倒数N层完成===========
        //=============3、三数取中法优化栈溢出问题===============
        int middle=middleValue(array,left,right);
        //与left交换
        swap(array,left,middle);
        //4、在区段中找基准
        int point=partitionHoare(array,left,right);//Hoare找基准
        //5、左右区段分别入栈
        if(left+1<point){
            //入栈左下标
            stack.push(left);
            //入栈右下标
            stack.push(point-1);
        }
        if(right-1>point){
            //入栈右区段
            //入栈左下标
            stack.push(point+1);
            //入栈右下标
            stack.push(right);
        }
        while(!stack.isEmpty()){
            //根不为空,继续分解
            //先取出两个元素
            //1、第一个元素赋给right
            right=stack.pop();
            //2、第二个元素赋给left
            left=stack.pop();
            //3、三数取中
            middle=middleValue(array,left,right);
            swap(array,middle,left);
            //4、找基准
            point=partitionHoare(array,left,right);
            //5、左右区段分别入栈
            if(left+1<point){
                //入栈左下标
                stack.push(left);
                //入栈右下标
                stack.push(point-1);
            }
            if(right-1>point){
                //入栈右区段
                //入栈左下标
                stack.push(point+1);
                //入栈右下标
                stack.push(right);
            }
        }
    }
    //测试快速排序-迭代运行时间
    public static void TestQuickSort2(int[] array){
        //记录开始时间
        long begin=System.currentTimeMillis();
        quickSort2(array);
        //记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("快速排序--递归耗时--->"+(end-begin));
    }

9、归并排序

归并排序是建立在归并操作上一种有效的排序算法,该算法采用分治法的一个典型应用,,将已经有序的子序列合并,得到完全有序的序列;即先使每一个子序列有序,再使子序列段间有序。若将两个有序表合并称为一个有序表,称为二路归并。

 

 
    /**
     * 归并排序
     * 时间复杂度:O(N*logN)
     * 空间复杂度:O(N)
     * 稳定性:稳定
     * @param array
     */
    public static void mergeSort(int[] array){
        int left=0;
        int right=array.length;
        mergeSortProcess(array,left,right);
    }

    private static void mergeSortProcess(int[] array, int left, int right) {
        //1、终止条件
        if(left>=right){
            return;
        }
        //2、找中间下标
        int mid=(left+right)/2;
        //3、开始递归,分解左右区段
        mergeSortProcess(array,left,mid);
        mergeSortProcess(array,mid+1,right);
        //4、合并过程
        merge(array,left,mid,right);
    }

    private static void merge(int[] array, int left, int mid, int right) {
        //定义一个临时数组
        int[] temp=new int[right-left+1];
        //定义临时数组下标
        int index=0;
        //确定每一个小数组的起始下标
        int start1=left;
        int end1=mid;
        int start2=mid+1;
        int end2=right;
        //归并排序,在归并的时候完成排序
        while(start1<end1&&start2<end2){
            //判断两个数组元素的大小
            if(array[start1]<array[start2]){
                //将start1下标加入到新数组中
                array[index++]=array[start1++];
            }else{
                array[index++]=array[start2++];
            }
        }
        //循环结束后,其中一个数组已经为空,将剩下的数组元素加入到临时数组中
        while(start1<=end1){
            temp[index++]=array[start1++];
        }
        while(start2<=end2){
            temp[index++]=array[start2++];
        }
        //将临时数组排好序的元素放到array中
        for (int i = 0; i < temp.length; i++) {
            array[i+left]=temp[i];
        }
    }
    // 测试快速排序
    private static void testMergeSort (int [] array) {
        // 记录开始时间
        long begin = System.currentTimeMillis();
        mergeSort(array);
        // 记录结束时间
        long end  = System.currentTimeMillis();
        System.out.println("归并排序耗时:" + (end - begin));
    }

9.1归并排序迭代法

  /**
     * 归并排序迭代法
     * @param array
     */
    public static void mergeSortItr(int[] array){
        //定义步长从1开始
        int gap=1;
        //开始循环
        while(gap<=array.length){
            for (int i = 0; i < array.length; i+=2*gap) {
                //确定左中右下标
                int left=i;
                int mid=i+gap-1;
                int right=mid+gap;
                //修正right和mid的值,防止越界
                if(mid>array.length){
                    mid=array.length-1;
                }
                if(right>array.length){
                    right=array.length-1;
                }
                //归并
                merge(array,left,mid,right);
            }
            //增大gap的值
            gap*=2;
        }
    }
    //测试归并排序-迭代
    public static void TestMergeSortItr(int[] array){
        //记录开始时间
        long begin=System.currentTimeMillis();
        mergeSortItr(array);
        //记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("归并排序-迭代法耗时"+(end-begin));
    }

9.2、归并排序特性总结

*归并排序的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘外排序问题

*时间复杂度:O(N*logN) 

*空间复杂度:O(N) 

*稳定性:稳定 

10、计数排序

计数排序是一种非比较排序,其核心是将序列中的元素作为键存储在额外数组空间中,而该元素的个数作为值存储在数组空间中,通过遍历该数组排序

适用于:

*序列中最大值和最小值之间的差值不能过大,这主要是防止建立数组时造成内存的浪费

*序列中存在的元素时整数,因为我们使用的时该元素作为键存储在额外的数组空间中,如果不是整数,不能作为键

步骤:

(1)从无序数组中取出最大值max,新建一个长度为max+1的数组

(2)遍历无序数组,取其中元素作为新建数组的索引,存在一个则新数组该索引所在的值自增

(3)遍历数组,当存在不为0的元素,取该元素的索引放入最终数组,并且该元素字键,直到为0,返回最终数组

/**
     * 计数排序
     * 时间复杂度:O(N+K)
     * 空间复杂度:O(K)
     * 稳定性:稳定
     * @param array
     */
    public static void countSort(int[] array){
        int minValue=array[0];
        int maxValue=minValue;
        //1、遍历数组,找到最大值和最小值
        for (int i = 0; i < array.length; i++) {
            if(array[i]<minValue){
                minValue=array[i];
            }
            if(array[i]>maxValue){
                maxValue=array[i];
            }
        }
        //2、创建一个数组,确认容量是maxValue-minValue+1
        int[] countArray=new int[maxValue-minValue+1];
        //3、再次遍历数组记录到对应元素的个数
        for (int i = 0; i < array.length; i++) {
            int index=array[i]-minValue;
            countArray[index]++;
        }
        //4、遍历计数数组
        int index=0;
        for (int i = 0; i < countArray.length; i++) {
            //根据计数数组对应下标的值,输出N个元素到原数组
            while(countArray[i]>0){
                int value=i+minValue;
                array[index]=value;
                countArray[i]--;
                index++;
            }
        }
    }
    //测试计数排序
    public static void TestCountSort(int[] array){
        //记录开始时间
        long begin=System.currentTimeMillis();
        countSort(array);
        //记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("归并排序-迭代法耗时"+(end-begin));
    }

11、测试类

    //---------构造数组---------
    //定义一个默认容量
    private static final int CAPACITY=1000_000;

    /**
     * 构造一个有序数组
     * @return
     */
    public static int[]  intitInorderArray(){
        //初始化一个数组
        int[] array=new int[CAPACITY];
        for (int i = 0; i <array.length ; i++) {
            array[i]=i;
        }
        return array;
    }

    /**
     * 构造一个无序数组
     * @return
     */
    public static int[] intitUniorderArray(){
        Random random=new Random();
        int[] array=new int[CAPACITY];
        for (int i = 0; i < array.length; i++) {
            array[i]= random.nextInt(CAPACITY);
        }
        return array;
    }

    public static void main(String[] args) {
        // System.out.println(Arrays.toString(intitInorderArray()));
        // System.out.println(Arrays.toString(intitUniorderArray()));
        System.out.println("数组长度"+CAPACITY);
        System.out.println("---有序数组---");
        TestShellSort(intitUniorderArray());
        //TestInsertSort(intitInorderArray());
        //TestSelectSort1(intitInorderArray());
        //TestSelectSort2(intitInorderArray());
        //TestHeapSort(intitInorderArray());
        TestBubbleSort(intitInorderArray());
        TestQuickSort(intitInorderArray());
        TestQuickSort2(intitInorderArray());
        TestMergeSortItr(intitInorderArray());
        TestMergeSortItr(intitInorderArray());
        TestCountSort(intitInorderArray());
        System.out.println("---无序数组---");
        int[] unorderArray=intitUniorderArray();
        TestShellSort(Arrays.copyOf(unorderArray,unorderArray.length));
        //TestInsertSort(Arrays.copyOf(unorderArray,unorderArray.length));
        //TestSelectSort1(Arrays.copyOf(unorderArray,unorderArray.length));
        //TestSelectSort2(Arrays.copyOf(unorderArray,unorderArray.length));
        TestHeapSort(Arrays.copyOf(unorderArray,unorderArray.length));
        //TestBubbleSort(Arrays.copyOf(unorderArray,unorderArray.length));
        TestQuickSort(Arrays.copyOf(unorderArray,unorderArray.length));
        TestQuickSort2(Arrays.copyOf(unorderArray,unorderArray.length));
        TestMergeSortItr(Arrays.copyOf(unorderArray,unorderArray.length));
        TestMergeSortItr(Arrays.copyOf(unorderArray,unorderArray.length));
        TestCountSort(Arrays.copyOf(unorderArray,unorderArray.length));
    }

运行结果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/606743.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python单元格间跳转超链接的重要性

Python单元格间跳转超链接的重要性 Python是一种高度流行的编程语言&#xff0c;它能够在各种领域得到广泛应用。作为一个Python工程师&#xff0c;单元格间跳转超链接是非常重要的。超链接是指一种指向另一个页面或目标的网页链接。在Python编程中&#xff0c;单元格间跳转超…

chatgpt赋能python:Python中的变量匹配技巧

Python中的变量匹配技巧 在Python编程中&#xff0c;匹配变量是一项非常重要的技巧。通过合理地匹配变量&#xff0c;我们可以快速地在代码中定位到具体的变量&#xff0c;提高代码的可读性和可维护性。 在本文中&#xff0c;我们将介绍Python中的一些变量匹配技巧&#xff0…

学成在线----day1

1、详细说说你的项目吧 从以下几个方面进行项目介绍&#xff1a; 1、项目的背景&#xff0c;包括&#xff1a;是自研还是外包、什么业务、服务的客户群是谁、谁去运营等问题。 2、项目的业务流程 3、项目的功能模块 4、项目的技术架构 5、个人工作职责 6、个人负责模块的详细…

【网路编程】UDP协议及UDP小练习之聊天室

目录 一、InetAddress类的使用 二、UDP协议之发送数据&#xff08;单播&#xff09; 三、UDP协议之接收数据 四、UDP小练习之聊天室 五、UDP之单播、组播、广播 &#xff08;一&#xff09;组播之发送数据、接收数据 &#xff08;二&#xff09;广播之发送数据、接收数据…

工业相机丢包排查步骤

机器视觉康耐视智能相机Insight-缺失外观检测 第一步:检查PC环境设置 l巨型帧/巨帧数据包是否已经设置成9KB,巨型帧在“本地连接->属性->配置->高级”的界面中 效果验证:如之前未配置9KB,请配置9KB后验证效果 l请确认现场电脑上是否有360安全卫士、360杀毒软件等…

软考A计划-电子商务设计师-电子商务系统规划

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

皮卡丘暴力破解

1.基于表单的暴力破解 随便输个账号和密码&#xff0c;用bp抓包 点击Action发送到Intruder,选中要爆破的位置 加入字典&#xff08;字典需下载&#xff09; 点击“Start attack”&#xff0c;开始爆破 发现这行长度和其他不一样&#xff0c;admin即为用户名&#xff0c;123456即…

033:Mapbox GL变换地图底图语言

第033个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中变换地图底图的语言。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共74行)安装插件相关API参考:专栏目标示例效果 配置方式 1)查看基础设置:…

华为芯片基地旁,龙华科技小镇大水坑片区城市更新单元旧改项目

项目位置&#xff1a;龙华观澜大水坑社区&#xff0c;位于梅观创新走廊九龙山产学研片区内 占地面积&#xff1a;总面积198万平方米&#xff0c;其中项目第一期60万平米开 发 商&#xff1a; 华润集团申报主体&#xff1a;华润置地项目&#xff1a;龙华科技小镇大水坑片区城市…

chatgpt赋能python:Python排序——让列表按大小排列

Python排序——让列表按大小排列 在Python编程的世界中&#xff0c;排序是一个非常重要的事情。不论是处理数据&#xff0c;还是进行各种算法实现&#xff0c;都需要将元素按照一定的方式排列。 而其中最常见的排序方式之一便是升序排序。升序排序顾名思义&#xff0c;就是将…

Leetcode 56 合并区间

Leetcode 56 合并区间 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/merge-intervals/description 博主Github&#xff1a;https://github.com/GDUT-Rp/LeetCode 题目&#xff1a; 以数组 intervals 表示若干个区间…

chatgpt赋能python:Python升序排序sort:让你的数据更易管理

Python升序排序sort&#xff1a;让你的数据更易管理 如果你是一位熟练的Python开发人员&#xff0c;你肯定听说过Python内置的sort()函数。这个函数是用来对列表、元组和可迭代对象进行排序的。 在本篇文章中&#xff0c;我们将着重介绍升序排序&#xff0c;探讨sort()函数的…

文件上传、MD5加密与验证码的功能实现

UUID工具类 1.概述&#xff1a;UUID 是通用唯一识别码&#xff08;Universally Unique Identifier&#xff09;的缩写。UUID 让分布式系统中的所有元素&#xff0c;都能有唯一的辨识信息&#xff0c;而不需要通过中央控制端来做辨识信息的指定。 是一个软件建构的标准&#x…

权限管理与jwt鉴权

权限管理与jwt鉴权 学习目标&#xff1a; 理解权限管理的需求以及设计思路实现角色分配和权限分配 理解常见的认证机制 能够使用JWT完成微服务Token签发与验证 权限管理 需求分析 完成权限&#xff08;菜单&#xff0c;按钮&#xff08;权限点&#xff09;&#xff0c;A…

【5.26 代随_38day】 动态规划基础理论、斐波那契数、爬楼梯、使用最小花费爬楼梯

动态规划基础理论、斐波那契数、爬楼梯、使用最小花费爬楼梯 动态规划基础理论1.动态规划的五部曲 斐波那契数1.动态规划的方法代码 爬楼梯图解步骤代码 使用最小花费爬楼梯图解步骤代码 动态规划基础理论 视频连接&#xff1a;动态规划解题方法论大曝光 &#xff01;| 理论基…

皮卡丘../../(目录遍历)/敏感信息泄露/PHP反序列化

一.目录遍历 1.概述 在web功能设计中,很多时候我们会要将需要访问的文件定义成变量&#xff0c;从而让前端的功能便的更加灵活。 当用户发起一个前端的请求时&#xff0c;便会将请求的这个文件的值(比如文件名称)传递到后台&#xff0c;后台再执行其对应的文件。 在这个过程中…

ArrayList的底层实现原理

目录 一、知识点回顾二、ArrayList 的 add() 和 remove() 的实现2.1 list.add(e) 实现原理2.2 list.remove() 实现原理 ArrayList的底层是通过数组实现的。 一、知识点回顾 数组特点&#xff1a; 存储区间是连续的&#xff0c;且占用内存严重&#xff0c;空间复杂度很大&…

第3节:cesium 离线地图下载(含教程+视频)

主要介绍两种方式。 第一种 望远网(web端地图下载) web端地图下载 第一步:选择资源发布方 第二步:选择地图类型以及路网 第三步:选择区域 支持区域选择和自定义区域两种方式 第四步:右键下载 提示:超过100个瓦片需要购买VIP

web前端 --- BOM编程、DOM编程

BOM编程&#xff08;browser object model -- 浏览器对象模型&#xff09; BOM给JavaScript提供用来操作浏览器的若干的"方法" 操作 在 js 看来&#xff0c;一个完整的浏览器包含如下组件&#xff1a; window窗口 // 整个浏览器的窗口 |-- history …

论文笔记--Efficient Estimation of Word Representations in Vector Space

论文笔记--Efficient Estimation of Word Representations in Vector Space 1. 文章简介2. 文章概括3 文章重点技术3.1 NNLM(Neural Network Language Model)3.1.1 NNLM3.1.2 RNNLM(Recurrent Neural Net Language Model) 3.2 Continuous Bag-of-Words Model(CBOW)3.3 Continuo…