堆排序与快速排序比较

      

 时间复杂度 最好时间复杂度最差时间复杂度 空间复杂度是否是稳定排序 
快速排序O(nlogn)O(nlogn)O(n*n)平方O(1)原地否(涉及到左右数据交换)
堆排序

O(nlogn)

O(nlogn)O(nlogn)O(1)原地否(涉及数据层与层的交换)

 

1.  10w 数据量两种排序速度基本相当,但是堆排序交换次数明显多于快速排序;10w+数据,随着数据量的增加快速排序效率要高的多,数据交换次数快速排序相比堆排序少的多。

2. 实际应用中,堆排序的时间复杂度要比快速排序稳定,快速排序的最差的时间复杂度是O(n*n),平均时间复杂度是O(nlogn)。堆排序的时间复杂度稳定在O(nlogn)。但是从综合性能来看,快速排序性能更好。

3.堆排序数据访问的方式没有快速排序友好。对于快速排序来说,数据是跳着访问的。比如:堆排序中,最重要的一个操作就是数据的堆化。比如下面的例子,对堆顶节点进行堆化,会依次访问数组下标是1.2.4.8的元素,而不是像快速排序那样,局部顺讯访问,所以,这样对cpu缓存是不友好的。

 

4. 对于同样的数据,在排序过程中,堆排序算法的数据交换次数要多于快速排序。排序有 有序度和逆序度两个概念。对于基于比较的排序算法来说,整个排序过程就是由两个基本的操作组成的,比较和交换(移动)。快速排序数据交换的次数不会比逆序度多。但是地排序的第一步是建堆,建堆过程会打乱数据原有的相对先后顺序,导致数据的有序度降低。比如,对于一组已经有序的数据来说,经过建堆之后,数据反而变得更无序了。

快排代码

   public void quickSort_W(int[] a) {
        if(a ==null || a.length<1) {
            return;
        }

        int n = a.length;
        quicksort_c(a, 0, n-1);
//        parttion(a,0,n-1);
    }
    private void quicksort_c(int[] a,int l,int r){
        if(l>=r) {
            return;

        }
        int m = parttion(a,l,r);
        quicksort_c(a, l, m-1);
        quicksort_c(a, m+1, r);
    }
    /**
     * 快排分区函数
     * @param a
     * @return
     */
    private int parttion(int[] a,int l,int r){

        int point = a[l];
        int i = l;
        int j = r;
        while ( i != j){
            while (a[j]>=point && i<j){
                j--;
            }

            while (a[i]<=point && i<j){
                i++;
            }
            if(i<j) {
                int temp = a[i];
                a[i] = a[j];
                a[j] =temp;
                changeTime ++;

            }


        }

        a[l] = a[i];
        a[i] = point;
//        parttion(a,l,i-1);
//        parttion(a,i+1,r);
//        System.out.println("i:"+i+"---"+point);
        return i;
    }

 

堆排序代码(包括:建堆和堆化)此处用的大顶堆

// n 表示数据的个数,数组 a 中的数据从下标 1 到 n 的位置。
public void sort(int[] a, int n) {
    changeTime = 0;
    buildHeap(a, n);
    int k = n;
    while (k > 1) {
        swap(a, 1, k);
        --k;
        heapify(a, k, 1);
    }
}


//建堆
private void buildHeap(int[] a, int n) {
    for (int i = n/2; i >= 1; --i) {
        heapify(a, n, i);
    }
}

private void heapify(int[] a, int n, int i) {
    while (true) {
        int maxPos = i;
        if (i*2 <= n && a[i] < a[i*2]) maxPos = i*2;
        if (i*2+1 <= n && a[maxPos] < a[i*2+1]) maxPos = i*2+1;
        if (maxPos == i) break;
        swap(a, i, maxPos);
        i = maxPos;
    }
}

//交换数据
private void swap(int[] a,int i,int j){
    int temp = a[i];
    a[i] = a[j];
    a[j] = temp;
    changeTime ++;
}

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值