快速排序 ,归并排序,堆排序,java实现,空间复杂度分析

三种排序算法时间复杂度均为nlgn,空间复杂度不同

快速排序

不需要额外内存 消耗lgn到n的栈空间

public  class QuickSort {


    static void quickSort(int[] array){
        quickSortofRange(array, 0, array.length-1);
    }
    
    // l r 为数组下标
    //两种方法  quickSortofRange quickSortofRange2
    static void quickSortofRange2(int[] array,int l,int r) {
        if(l>=r) return;
        int left=l,right=r;
        int pivot=array[l];
        while (l <r) {
            while (l<r&& pivot<= array[r]) {
                r--;
            }
            if(l<r)
                array[l]=array[r];
            while (l<r&& pivot>= array[l]) {
                l++;
            }
            if(l<r)
                array[r] = array[l];

        }
        array[l]=pivot;
        quickSortofRange2(array, left, l-1);
        quickSortofRange2(array, l+1, right);
    }


    static void quickSortofRange(int[] array,int l,int r) {
        if(l>=r) return;
        int left=l,right=r;
        int pivot=array[l];
        l++;
        while (l <=r) {
            while (array[l] <= pivot && array[l] <= array[r]) {
                l++;
            }
            while (array[r] >= pivot && array[r] >=array[l]) {
                r--;
            }
            if (r > l) {
                int tmp=array[l];
                array[l]=array[r];
                array[r]=tmp;
            }
        }

        //与移动顺序有关 先左 后右 则是主元和高的换
        while (array[r] >= pivot && array[r] >=array[l]) {
            r--;
        }
        if (array[r] < pivot) {
            array[left]=array[r];
            array[r]=pivot;
        }

        quickSortofRange(array, left, r-1);
        quickSortofRange(array, r+1, right);
    }



    public static void heapSort(int[] Array){
        //mergeSortofRange(Array,0,Array.length-1);
    }

}

归并排序

归并时需要一个额外一个大小为n的数组

public class MergeSort {
    static int[] tempArray;//如果归并过程中new临时数组,空间复杂度变为nlgn
    public static void mergeSort(int[] Array){
        tempArray=new int[Array.length];
        mergeSortofRange(Array,0,Array.length-1);
    }
    public static void mergeSortofRange(int[] Array,int l,int r){
        if(r==l) return; //lenth==1
        int mid=(l+r)/2; //单数长度多分给左半一个

        mergeSortofRange(Array, l,mid);
        mergeSortofRange(Array, mid+1,r);
        //merge

        int i=l,j=mid+1;
        for (int k = l; k <= r; k++) {
            if (Array[i] <= Array[j]) {
                tempArray[k]=Array[i];
                if(i<mid) i++;
                else {
                    System.arraycopy(Array, j, tempArray, ++k, r-k+1);
                    break;
                }
            }
            else {
                tempArray[k]=Array[j];
                if(j<r) j++;
                else {
                    System.arraycopy(Array, i, tempArray, ++k, r-k+1);
                    break;
                }
            }
        }
        System.arraycopy(tempArray, l, Array, l, r-l+1);
    }
}

堆排序

需要一个堆对象,至少包含一个大小为n数组

public class HeapSort {
    public static <E extends Comparable<E>> void heapSort(E[] lst) {
        Heap<E> heap=new Heap<>(lst);
        for (int i = 0; i < lst.length; i++) {
            lst[i]=heap.remove();
        }
    }
}

class Heap<E extends Comparable<E>>{
    private ArrayList<E> list=new ArrayList<>();
    public Heap(){}

    public Heap(E[] objects) {
        for (int i = 0; i < objects.length; i++) {
            add(objects[i]);
        }
    }

    //(childindex-1)/2=parentindex  大顶堆,子大于父交换
    public void add(E object) {
        list.add(object);
        int currentIndex=list.size()-1;
        while (currentIndex > 0) {
            int parentIndex=(currentIndex-1)/2;
            if (list.get(currentIndex).compareTo(list.get(parentIndex)) > 0) {
                E temp=list.get(currentIndex);
                list.set(currentIndex, list.get(parentIndex));
                list.set(parentIndex, temp);
            }
            else break;
            currentIndex=parentIndex;
        }
    }

    //移除头 把尾结点送到头 递归向下选择子节点中大的作为当前头交换
    public E remove() {
        if(list.size()==0) return null;
        if (list.size()==1) return list.remove(0);

        E RemoveObject=list.get(0);
        E removeLast=list.remove(list.size()-1);
        list.set(0, removeLast);


        int currentIndex=0;
        while(currentIndex<list.size()){
            int leftChildIndex=(currentIndex<<1)+1;
            int rightChildIndex=leftChildIndex+1;
            int maxIndex;
            if(leftChildIndex>=list.size()) break;
            if(rightChildIndex<list.size()&&list.get(rightChildIndex).compareTo(list.get(leftChildIndex))>0)
                maxIndex=rightChildIndex;
            else maxIndex=leftChildIndex;

            if (list.get(currentIndex).compareTo(list.get(maxIndex)) < 0) {
                E temp=list.get(maxIndex);
                list.set(maxIndex, list.get(currentIndex));
                list.set(currentIndex, temp);
                currentIndex=maxIndex;
            }else break;
        }
        return RemoveObject;
    }

    public  int getSize() {
        return list.size();
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值