最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言實(shí)現(xiàn)大頂堆的示例代碼

 更新時(shí)間:2022年07月22日 08:57:43   作者:MT_125  
最大堆,又稱大根堆(大頂堆)是指根結(jié)點(diǎn)(亦稱為堆頂)的關(guān)鍵字是堆里所有結(jié)點(diǎn)關(guān)鍵字中最大者,屬于二叉堆的兩種形式之一。本文將用C語言實(shí)現(xiàn)大頂堆,感興趣的可以了解一下

堆的實(shí)現(xiàn)

1.堆結(jié)構(gòu)

邏輯結(jié)構(gòu)上類似于 一棵 “樹”

2.堆的種類

大頂堆結(jié)構(gòu): 一種特殊的樹:其每個(gè)子節(jié)點(diǎn)均比母節(jié)點(diǎn)要小

小頂堆結(jié)構(gòu): 同理:其每個(gè)子節(jié)點(diǎn)均比母節(jié)點(diǎn)要大

結(jié)構(gòu)圖示:

3.大頂堆代碼實(shí)現(xiàn)

這里實(shí)現(xiàn)堆 用循序表的方式

①初始化:

typedef int Heaptype;
 
typedef struct Heap
{
    Heaptype* head;   
    int size;         //記錄堆總?cè)萘?
    int capacity;     //記錄當(dāng)前數(shù)據(jù)總個(gè)數(shù)
}Heap;
 
//堆的初始化
void Heap_Init(Heap* pphead)
{
    assert(pphead);
    pphead->head = NULL;
    pphead->size = 0;
    pphead->capacity = 0;
}

②插入數(shù)據(jù):

實(shí)現(xiàn)細(xì)節(jié):數(shù)據(jù)在插入的同時(shí),要進(jìn)行數(shù)據(jù)結(jié)構(gòu)的調(diào)整,使樹頂始終保持最大數(shù)

如果新插入節(jié)點(diǎn)比母節(jié)點(diǎn)大的話,要進(jìn)行交換 ,因此將這個(gè)調(diào)整結(jié)構(gòu)的環(huán)節(jié)獨(dú)立出來

即:“向上調(diào)整”。

 向上調(diào)整:因?yàn)椴迦霐?shù)據(jù)時(shí):新數(shù)據(jù)默認(rèn)儲存在順序表尾,因此其邏輯上是在堆的底部,

所以,當(dāng)新數(shù)據(jù)比母節(jié)點(diǎn)大時(shí),它將與邏輯上處于其上方的母節(jié)點(diǎn)交換,稱為

向上調(diào)整。

注:向上調(diào)整有時(shí)不止調(diào)整一次 ,還有可能調(diào)整多次,直到每個(gè)節(jié)點(diǎn)都在其相應(yīng)位置 。

流程圖解:

大頂堆插入流程

細(xì)節(jié)點(diǎn):因?yàn)閿?shù)據(jù)是以順序表的方式儲存,所以子節(jié)點(diǎn)的下標(biāo)與母節(jié)點(diǎn)的下標(biāo)符合

公式:parent = (child - 1)/2 ;(按照此公式帶入計(jì)算就理解了) 

//向上調(diào)整
void adjust_up(Heap* pphead)
{
    int child = pphead->capacity;
    int parent = (child - 1) / 2;
    for (; pphead->head[parent] < pphead->head[child];)//判斷是否符合大頂堆
    {
        swap(&(pphead->head[parent]),&(pphead->head[child]));//進(jìn)行交換
        child = parent;
        parent = (child - 1) / 2;
    }
}
 
//插入數(shù)據(jù)
void Heap_push(Heap* pphead, Heaptype data)
{
    assert(pphead);
    //判斷是否滿容量并擴(kuò)容
    Heap_realloc(pphead);
    pphead->head[pphead->capacity] = data;
    //向上調(diào)整
    adjust_up(pphead);
    pphead->capacity++;
}

③刪除數(shù)據(jù):為了避免因?yàn)橹苯觿h除頭部數(shù)據(jù)導(dǎo)致整個(gè)堆的結(jié)構(gòu)打亂,

這里先將頭部數(shù)據(jù)與尾數(shù)據(jù)交換,然后將尾部數(shù)據(jù)刪除,接著使用“向下調(diào)整”,即:將換上來的頂部數(shù)據(jù)向下與其子節(jié)點(diǎn)比較調(diào)整,直至符合大頂堆結(jié)構(gòu)為止。

注:1.大頂堆向下調(diào)整時(shí),母節(jié)點(diǎn)要與兩個(gè)子節(jié)點(diǎn)中較大的一個(gè)交換 ,因此要比較一下。

2.這里下標(biāo)的計(jì)算公式為:左孩子:child = (parent * 2) + 1

右孩子:child = (parent * 2) + 2

3.計(jì)算孩子下標(biāo)時(shí)要避免越界,避免將母節(jié)點(diǎn)與不屬于堆中的數(shù)據(jù)比較。

//刪除數(shù)據(jù)
void Heap_pop(Heap* pphead)
{
    assert(pphead);
    assert(pphead->capacity > 0);      //防止堆為空
    //將頂部數(shù)據(jù)與尾部數(shù)據(jù)交換
    swap(&(pphead->head[0]),&( pphead->head[pphead->capacity-1]));
    pphead->capacity--;
    //向下調(diào)整
    adjust_down(pphead,0);
}
 
//向下調(diào)整
void Adjust_down(int* a, int size, int parent)
{
    assert(a);
    for (int child = parent * 2 + 1; child <= size; child = parent * 2 + 1)
    {
        //默認(rèn)用左孩紙與母節(jié)點(diǎn)比較,如果右孩紙比左孩紙大且不越界則交換
        if (a[child] > a[child + 1] && child + 1 <= size)
            child = child + 1;
        //比較孩紙和母節(jié)點(diǎn)
        if (a[child] < a[parent])
        {
            int temp = a[child];
            a[child] = a[parent];
            a[parent] = temp;
        }
        //向下繼續(xù)比較
        parent = child;
    }
}

④擴(kuò)容 || 判空 || 取頂數(shù)據(jù) || 銷毀堆

//判斷是否擴(kuò)容
void Heap_realloc(Heap* pphead)
{
    assert(pphead);
    if (pphead->size == pphead->capacity)
    {
        Heaptype Newsize = (pphead->size == 0) ? 4 : (pphead->size * 2);
        Heaptype* Newhead = (Heaptype*)realloc(pphead->head,sizeof(Heaptype) * Newsize);
        if (Newhead == NULL)
        {
            perror("realloc");
            exit(-1);
        }
        pphead->head = Newhead;
        pphead->size = Newsize;
    }
}
 
//判斷堆是否為空
bool Heap_Empty(Heap* pphead)
{
    if (pphead->capacity)
        return false;
    return true;
}
//取對頂數(shù)據(jù)
Heaptype Heap_top(Heap* pphead)
{
    return pphead->head[0];
}
//銷毀堆
void Heap_Destory(Heap* pphead)
{
    assert(pphead);
    free(pphead->head);
    pphead->head = NULL;
    pphead->size = 0;
    pphead->capacity = 0;
}

以上就是C語言實(shí)現(xiàn)大頂堆的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于C語言大頂堆的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

合山市| 竹北市| 方城县| 绩溪县| 溧水县| 砚山县| 遂平县| 乌鲁木齐县| 邹平县| 托克托县| 景宁| 陇南市| 广德县| 正安县| 武宁县| 河东区| 宣城市| 射洪县| 朝阳县| 厦门市| 郸城县| 广丰县| 乌恰县| 积石山| 平顺县| 永济市| 台东县| 莆田市| 绥棱县| 镇平县| 景德镇市| 双鸭山市| 景德镇市| 林州市| 枣庄市| 台东市| 西吉县| 辽宁省| 佛坪县| 涡阳县| 洛扎县|