排序6:堆排序

http://blog.csdn.net/qq_27703417/article/details/70952603

http://www.iqiyi.com/v_19rrhzzs1k.html

 

对于之后任意的元素i,它的左孩子下标是2*i+1,右孩子下标是2*i+2,它的父结点下标是(i-1)/2

 

public static int[] heapSort(int[] A, int n) {  
        //1,建立大根堆  
            A=buildMaxHap(A);  
            //2,调整排序  
            for(int i=n-1;i>0;i--){  
                //堆顶和堆底元素交换  
                int tem=A[0];  
                A[0]=A[i];  
                A[i]=tem;  
                adjustHeap(A, 0, i);//将剩余的元素整理成堆  
            }  
            return A;  
        }  
       
        private static int[] buildMaxHap(int[] A) {  
            //从最后一个结点的父节点开始,对之前的每个结点(二叉堆)进行调整  
            System.out.println("");
            for(int i=(A.length-1)/2;i>=0;i--){  
                adjustHeap(A,i,A.length);  
                System.out.println(Arrays.toString(A));
            }  
            System.out.println("");
            return A;  
        }  
          
        //堆的调整:将元素A[k]自下往上逐步调整树形结构  
        private static void adjustHeap(int[] A, int k, int len) {  
            //将结点A[k]作为一个空穴下滤,不要直接交换值,当确定好了位置后再进行赋值  
            int tem=A[k];  
            for(int i=2*k+1;i<len;i=2*i+1){  
                //将结点A[k]进行下滤,直到找到合适的位置或者沉到底  
                //左右节点中,找一个较大的值与父节点比较
                if(i!=len-1 && A[i]<A[i+1]){  
                    i++;//右>左,取右  
                }  
                if(tem>A[i]){  
                    //根结点比孩子大,找到合适的位置,不需要再下滤  
                    break;  
                }else{  
                    //否则,改变根植,并继续向下调整  
                    A[k]=A[i];  
                   //修改k值,以便继续向下调整,只移动孩子结点到上面,空穴下沉,不是每次都交换值  
                    k=i;  
                }  
            }  
            //A[k]即空穴找合适的位置了在将原来的值赋值回来  
            A[k]=tem;   
        }  

 

posted on 2017-08-23 10:32  zhangxiaoyu  阅读(119)  评论(0)    收藏  举报

导航