冒泡排序

//交换数组两个位置的数
    static void swap(int[] arr,int i,int j){
        int temp;
        temp=arr[j];
        arr[j]=arr[i];
        arr[i]=temp;
    }

    static void BubbleSort(int[] arr,int length){
        int i,j;
        //表示本趟冒泡是否发生交换的标志
        boolean flag;
        //一趟排序的过程
        for (i=0;i<length-1;i++){
            flag=false;
            //从尾往前寻找
            for (j=length-1;j>i;j--){
                //若为逆序,则交换
                if (arr[j-1]>arr[j]){
                    swap(arr,j-1,j);
                    flag=true;
                }
            }
            //如果本趟没有排序,说明序列已经有序
            if (flag==false)return;
        }
    }

空间效率:因为使用了常数个辅助单元,因而空间复杂度为O(1)
时间效率:当初始序列有序时,显然第一趟冒泡后flag依然为false,即本趟冒泡没有元素进行交换,从而跳出循环,比较次数为n-1,移动次数为0,从而最好情况下的时间复杂度为O(n);
当初始序列为逆序时,需要进行n-1趟排序,第i趟排序要进行n-i次关键字比较,而且每次比较后都必须移动2次元素来交换元素的位置。从而最坏情况下的时间复杂度为O(n^2), 其平均复杂度也为O(n^2)。

快速排序

//快速排序
    static void QuickSort(int[] arr,int low,int high){
        //递归跳出条件
        if(low<high){
            //划分操作,将arr[low...high]划分为满足上述条件的两个子表
            int pivotpos=Partition(arr,low,high);
            //依次对两个子表进行递归排序
            QuickSort(arr,low,pivotpos-1);
            QuickSort(arr,pivotpos+1,high);
        }
    }

    //根据枢轴元素对序列进行排序并划分两部分
    static int Partition(int[] arr,int low,int high){
        //将当前表中第一个元素作为枢轴元素
        int pivot=arr[low];
        //循环跳出条件
        while (low<high){
            //从后面寻找比枢轴元素小的元素
            while (low<high&&arr[high]>=pivot)
                --high;
            //将比枢轴元素小的元素移动左端
            swap(arr,low,high);
            //从左端寻找比枢轴元素大的元素
            while (low<high&&arr[low]<=pivot)
                ++low;
            //将比枢轴元素大的元素移动右端
            swap(arr,high,low);
        }
        //枢轴元素放到最终位置
        arr[low]=pivot;
        return low;
    }

空间效率:由于快速排序时递归的,需要借助一个递归工作栈来保存每层递归调用的必要信息,其容量与递归调用的最大深度一致。最好的情况下为O(log2n);最坏情况下,因为要进行n-1次递归调用了,所以栈的深度为O(n);平均情况下,栈的深度为O(log2n)。

时间效率:快速排序的运行时间与划分是否对称有关,快速排序的最坏情况发生在两个区域分别包含n-1个元素和0个元素,这种最大限度的不对称性若发生每层递归上,即对应于初始排序表基本有序或逆序时,就得到最坏情况下的时间复杂度O(n^2)

提高算法效率的方法:一种方法是尽量取一个可以将数据中分的枢轴元素,如从序列的头尾及中间选取三个元素,再取这三个元素的中间值作为最终的枢轴元素;或者随机地从当前表中选取枢轴元素,这样做都会使最坏情况在实际排序中不会发生。

在最理想的状况下,即Partition()可能做到最平衡的划分,得到两个子问题的大小都不可能大于n/2,在这种情况下,快速排序的运行速度将得到大大提升,此时,时间复杂度为O(nlog2n)。
好在快速排序平均情况下的运行时间与最佳情况下的运行时间很接近。所以快速排序是所有内部排序算法中平均性能最优的排序算法。

最后main方法看一下

public static void main(String[] args) {
        int[] arr=new int[]{998857732,995773975,986263711,970050582,978672815,946770900,884642435,885254231,830140516,917959651,768122842,937296273,546931356,861262547,764532283,965184299,918973856,915272981,830623614,728999048,693597252,631219735,884688278,984427390,714012242,537616843,536343860,521612397,659978110,445747969,433183457,641532230,480363996,586696306,31693639,805374069,303753633,215386675,261627544,604354651,733048764,393354006,631784130,241316335,427529125,111935818,698504118,109686701,64838842,353487181,82447697,177571868,691252458,230964510,453463919,340316511,280992325,13701823,77481420,544069623,544526209,193715454,157540946,427514727,292446044,782703840,219297819,151485185,256184773,570872277,695760794,738644784,784607555,433518449,440403918,281397572,493886311,970466103,738026287,819959858,119093579,411203381,306242389,84356804,42607214,462370265,294497342,70309112,158982405,513023688,740856884,784337461,17092337,633020080,387052570,421701576,298738196,54807658,472147510,169670404};
        
        //冒泡排序
//        BubbleSort(arr,arr.length);
        QuickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }