堆排序-java实现

来源:互联网 发布:淘宝网被子四件套 编辑:程序博客网 时间:2024/06/04 21:05

堆排序主要的过程就是建立大顶堆或者小顶堆,然后调整堆,最后进行堆排序。
①建堆,建堆是不断调整堆的过程,从len/2处开始调整,一直到第一个节点,此处len是堆中元素的个数。建堆的过程是线性的过程,从len/2到0处一直调用调整堆的过程,相当于o(h1)+o(h2)…+o(hlen/2) 其中h表示节点的深度,len/2表示节点的个数,这是一个求和的过程,结果是线性的O(n)。
②调整堆:调整堆在构建堆的过程中会用到,而且在堆排序过程中也会用到。利用的思想是比较节点i和它的孩子节点left(i),right(i),选出三者最大(或者最小)者,如果最大(小)值不是节点i而是它的一个孩子节点,那边交互节点i和该节点,然后再调用调整堆过程,这是一个递归的过程。调整堆的过程时间复杂度与堆的深度有关系,是lgn的操作,因为是沿着深度方向进行调整的。
③堆排序:堆排序是利用上面的两个过程来进行的。首先是根据元素构建堆。然后将堆的根节点取出(一般是与最后一个节点进行交换),将前面len-1个节点继续进行堆调整的过程,然后再将根节点取出,这样一直到所有节点都取出。堆排序过程的时间复杂度是O(nlgn)。因为建堆的时间复杂度是O(n)(调用一次);调整堆的时间复杂度是lgn,调用了n-1次,所以堆排序的时间复杂度是O(nlgn)

其中建堆的时候:其一,由与堆排序采用的堆满足完全二叉树的性质,所以初始化堆要从len/2处开始调整,一直到第一个节点,这个很重要;其二,还有一点很重要,就是在调整堆的时候要注意到堆的无序长度一直在减少,写代码这点很容易忽视。

package 排序;public class HeapSort1 {    public static int[] heapSort(int[] A,int n){        buildMaxHeap(A);        print(A);        heapSort(A);        return A;    }    //堆排序    public static void heapSort(int[] A){        for(int i = A.length - 1;i > 0;i--){            System.out.println("zcf: ");            print(A);            swap(A, i, 0);            //这里面堆的空间就是i的长度,不断的减少            maxHeap(A, i, 0);        }    }    //建立大顶堆    public static void buildMaxHeap(int[] A){        int startIndex = getParentIndex(A.length - 1);        for(int i = startIndex;i >= 0;i--){            //这里面堆的空间就是数组的初识长度,这是初始化大顶堆            maxHeap(A, A.length, i);        }    }    //调整    public static void maxHeap(int[] A,int heapSize,int index){        int left = getLeftChildIndex(index);        int right = getRightChildIndex(index);        int largest = index;        if(left < heapSize && A[left] > A[index]){            largest = left;        }        if(right < heapSize && A[right] > A[largest]){            largest = right;        }        // 得到最大值后可能需要交换,如果交换了,其子节点可能就不是最大堆了,需要重新调整        if(largest != index){            swap(A, index,largest);            //调整子节点的时候堆的空间长度不变            maxHeap(A, heapSize,largest);        }    }    public static int getLeftChildIndex(int current){        return (current << 1) + 1;    }    public static int getRightChildIndex(int current){        return (current << 1) + 2;    }    public static int getParentIndex(int current){        return (current - 1) >> 1;    }    public static void swap(int[] data,int i,int j){        /*if (i == j) {              return;          }        data[i] = data[i] + data[j];        data[i] = data[i] - data[j];        data[j] = data[i] - data[j];*/        int temp = data[i];        data[i] = data[j];        data[j] = temp;    }    public static void print(int[] A){        for (int i = 0; i < A.length; i++) {              System.out.print(A[i] + "\t");          }          System.out.println();     }    public static void print1(int[] data) {        int pre = -2;        for (int i = 0; i < data.length; i++) {            if (pre < (int) getLog(i + 1)) {                pre = (int) getLog(i + 1);                System.out.println();            }            System.out.print(data[i] + "|");        }    }    private static double getLog(double param) {        return Math.log(param) / Math.log(2);    }    public static void main(String[] argS){         int[] A = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 };          heapSort(A, A.length);         print(A);    }}
1 0
原创粉丝点击