国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
堆排序詳解以及java實(shí)現(xiàn)

         堆排序和合并排序一樣,是一種時(shí)間復(fù)雜度為O(nlgn)的算法,同時(shí)和插入排序一樣,是一種就地排序算法(不需要額外的存儲空間)。堆排序需要用到一種被稱為最大堆的數(shù)據(jù)結(jié)構(gòu),與java或者lisp的gc不一樣,這里的堆是一種數(shù)據(jù)結(jié)構(gòu),他可以被視為一種完全二叉樹,即樹里面除了最后一層其他層都是填滿的。也正是因?yàn)檫@樣,樹里面每個(gè)節(jié)點(diǎn)的子女和雙親節(jié)點(diǎn)的序號都可以根據(jù)當(dāng)前節(jié)點(diǎn)的序號直接求出。

  Parent(i)=i/2

  Left(i)=2*i

Right(i)=2*i+1

 

 

如上圖所示,1位置的子女節(jié)點(diǎn)分別為2,3  2節(jié)點(diǎn)的子女節(jié)點(diǎn)為4,5 2的雙親節(jié)點(diǎn)為1 考察其他節(jié)點(diǎn)也很容易發(fā)現(xiàn)上述關(guān)系。最大堆是一種特殊的堆,其特點(diǎn)是每個(gè)雙親節(jié)點(diǎn)的值都比子女節(jié)點(diǎn)大。他的這一特點(diǎn)使得他可以實(shí)現(xiàn)nlgn的就地排序?,F(xiàn)在我們先來看看怎么構(gòu)建和保持一個(gè)最大堆。

最大堆的構(gòu)建和保持

         我們現(xiàn)在有一個(gè)數(shù)組A,大小是n,假設(shè)其中元素按照完全二叉樹的方式排列。如何將其構(gòu)造成一個(gè)最大堆?首先我們知道最大堆的每個(gè)子樹都符合最大堆的性質(zhì)(根節(jié)點(diǎn)值大于所有子節(jié)點(diǎn))。同時(shí)我們知道序號為(n/2+1)~n的元素都是葉子節(jié)點(diǎn)(因?yàn)槠渥优?jié)點(diǎn)的序號都大于n,即說明沒有子女節(jié)點(diǎn)),因此我們構(gòu)建最大堆的操作就在序號為1~n/2的元素內(nèi)進(jìn)行(其他元素已滿足最大堆性質(zhì))。我們定義如下操作maxify(i):將以i位置節(jié)點(diǎn)為根的子樹改造成最大堆。其操作內(nèi)容如下:對于每個(gè)節(jié)點(diǎn)i,我們考察他與子女節(jié)點(diǎn)的大小,如果他比某個(gè)子女節(jié)點(diǎn)小,則將他與子女節(jié)點(diǎn)中最大的那個(gè)互換位置,然后在相應(yīng)的子女節(jié)點(diǎn)位置重復(fù)操作,直到到達(dá)堆的葉子節(jié)點(diǎn)或者考察的位置比子女節(jié)點(diǎn)的值都要大為止。由此可知我們構(gòu)造最大堆buildmaxheap的過程就是在每個(gè)內(nèi)部節(jié)點(diǎn)上調(diào)用maxify過程,依次到樹的根部,此時(shí)其左右子樹都是最大堆,現(xiàn)在在根節(jié)點(diǎn)調(diào)用maxify即完成了最大堆的構(gòu)造。

堆排序的操作

         有了最大堆的基礎(chǔ)結(jié)構(gòu)后,我們就可以利用最大堆的性質(zhì)進(jìn)行排序HeapSort,我們從根節(jié)點(diǎn)開始操作,因?yàn)楦?jié)點(diǎn)是這個(gè)數(shù)組中最大的元素,因此我們將其于數(shù)組中最后一個(gè)元素對換(排序后,最大元素應(yīng)該在最后)將heapsize減1,然后再在根節(jié)點(diǎn)出調(diào)用maxify過程將新的堆重新最大堆化。依次循環(huán),我們每次都能將現(xiàn)有堆中最大的元素放到堆末尾。最后就完成了整個(gè)排序過程。操作情況見下圖(只列出了前4步)

        

public class MaxHeap {int[] heap;int heapsize;public MaxHeap(int[] array){    this.heap=array;        this.heapsize=heap.length;}public void BuildMaxHeap(){    for(int i=heapsize/2-1;i>=0;i--)    {        Maxify(i);//依次向上將當(dāng)前子樹最大堆化    }}public void HeapSort(){    for(int i=0;i<heap.length;i++)    {        //執(zhí)行n次,將每個(gè)當(dāng)前最大的值放到堆末尾        int tmp=heap[0];        heap[0]=heap[heapsize-1];        heap[heapsize-1]=tmp;        heapsize--;        Maxify(0);    }}public void Maxify(int i){    int l=Left(i);    int r=Right(i);    int largest;        if(l<heapsize&&heap[l]>heap[i])        largest=l;    else        largest=i;    if(r<heapsize&&heap[r]>heap[largest])        largest=r;    if(largest==i||largest>=heapsize)//如果largest等于i說明i是最大元素 largest超出heap范圍說明不存在比i節(jié)點(diǎn)大的子女        return ;    int tmp=heap[i];//交換i與largest對應(yīng)的元素位置,在largest位置遞歸調(diào)用maxify    heap[i]=heap[largest];    heap[largest]=tmp;    Maxify(largest);}public void IncreaseValue(int i,int val){    heap[i]=val;    if(i>=heapsize||i<=0||heap[i]>=val)        return;    int p=Parent(i);    if(heap[p]>=val)        return;    heap[i]=heap[p];    IncreaseValue(p, val);}private int Parent(int i){    return (i-1)/2;}private int Left(int i){    return 2*(i+1)-1;}private int Right(int i){    return 2*(i+1);}}

 

public class Demo {public static void main(String[] args){    int[] array=new int[]{1,2,3,4,7,8,9,10,14,16};    MaxHeap heap=new MaxHeap(array);    System.out.println("執(zhí)行最大堆化前堆的結(jié)構(gòu):");    printHeapTree(heap.heap);    heap.BuildMaxHeap();    System.out.println("執(zhí)行最大堆化后堆的結(jié)構(gòu):");    printHeapTree(heap.heap);    heap.HeapSort();    System.out.println("執(zhí)行堆排序后數(shù)組的內(nèi)容");    printHeap(heap.heap);    }private static void printHeapTree(int[] array){    for(int i=1;i<array.length;i=i*2)    {        for(int k=i-1;k<2*(i)-1&&k<array.length;k++)        {            System.out.print(array[k]+" ");        }        System.out.println();    }    }private static void printHeap(int[] array){    for(int i=0;i<array.length;i++)    {        System.out.print(array[i]+" ");    }}}

 

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
排序算法
《算法導(dǎo)論》讀書筆記之第6章 堆排序
Python 面試題
最大堆排序
【算法】4 五張圖帶你體會堆算法
關(guān)于數(shù)據(jù)結(jié)構(gòu)堆的二三事之第一話:二叉堆(上) - 竇小蹦(fairyroad) - CSD...
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服