資料結構 堆專題總結

2021-08-27 05:30:14 字數 4556 閱讀 3373

專題主要內容

堆的概念、性質

堆的建立

堆的插入&刪除

堆的應用

堆的概念

堆(heap),這裡所說的堆是資料結構中的堆,而不是記憶體模型中的堆。堆通常是乙個可以被看做一棵樹,它滿足下列性質:

[性質一]堆中任意節點的值總是不大於(不小於)其子節點的值;

[性質二]堆總是一棵完全樹。

將任意節點不大於其子節點的堆叫做小堆或小根堆,而將任意節點不小於其子節點的堆叫做大堆或大根堆。常見的堆有二叉堆、左傾堆、斜堆、二項堆、斐波那契堆等等。

二叉堆

二叉堆一般都通過」陣列」來實現。陣列實現的二叉堆,父節點和子節點的位置存在一定的關係。有時候,我們將」二叉堆的第乙個元素」放在陣列索引0的位置,有時候放在1的位置。當然,它們的本質一樣(都是二叉堆),只是實現上稍微有一丁點區別。

二叉堆性質

在前面,我們已經了解到:」最大堆」和」最小堆」是對稱關係。這也意味著,了解其中之一即可。本節的**解析是以」最大堆」來進行介紹的。

二叉堆的核心是」新增節點」和」刪除節點」,理解這兩個演算法,二叉堆也就基本掌握了。下面對它們進行介紹。

建立新增&刪除

堆操作相關參考**

heap.h

//定義堆結構(動態線性表實現)

typedef

int htdatatype;

typedef

struct heap

heap;

//初始化堆

void heapinit(heap* hp, htdatatype* a, int n);

//堆的銷毀(釋放malloc出來的空間)

void heapdestory(heap* hp);

//向堆裡插入乙個資料

//彈出堆頂的資料

//取堆頂資料

htdatatype heaptop(heap* hp);

//堆的大小

int heapsize(heap* hp);

//判斷堆是否為空(空返回0,非空返回1)

int heapempty(heap* hp);

//向下調堆

void adjustdown(htdatatype* a, int n, int parent);

//向上調堆

void adjustup(htdatatype* a, int n, int child);

heap.c

#include "heap.h"

//交換兩個資料

static void swap(htdatatype* a, htdatatype* b)

//向下調堆

void adjustdown(htdatatype* a, int n, int

parent)

//如果建大堆,如果雙親小於孩子,則交換

if (a[parent] < a[child])

else

}}//初始化堆

void heapinit(heap* hp, htdatatype* a, int n)

//2.從第乙個非葉子結點開始向上調整(n為陣列大小,所以n-1為陣列最後乙個元素的下標)

for (i = (n - 2) / 2; i >= 0; i--)

}//堆的銷毀(釋放malloc出來的空間)

void heapdestory(heap* hp)

//向上調整堆

void adjustup(htdatatype* a, int n, int child)

else

}}//向堆裡插入乙個資料

}//1.先將資料入到堆的最後乙個位置

hp->a[hp->size] = x;

hp->size++;

//2.向上調堆一次

adjustup(hp->a, hp->size, hp->size - 1);

}//彈出堆頂的資料

//取堆頂資料

htdatatype heaptop(heap* hp)

//堆的大小

int heapsize(heap* hp)

//空返回1,非空返回0

int heapempty(heap* hp)

//列印堆的元素

void printheap(heap* hp)

printf("\n");

}

!!!經典練習【c++版】
實現堆建立,插入及刪除

優先順序佇列

100w個數中找到最大的前k個數

堆排序

解答:1. 實現堆建立,插入及刪除在實現堆的建立時,我們以大堆為例,大堆的建立需要自上向下調整堆,建立堆的時間複雜度為o(log2 n)。

//向下調整

void adjustdown(vector

& arr,int parent,int size)

else

break;

}}//建立

void createheap(vector

& arr) }

//堆刪除堆頂元素的時間複雜度為o(log2 n)

void deleteheap(vector

& arr)

}//堆插入的時間複雜度為o(log2 n)

void adjustup(vector

& arr,int child)

else

break;

}} void insertheap(vector

& arr,int data)

2.優先順序佇列優先順序佇列的底層為堆,是一種特殊的佇列,這種佇列會自動的把佇列裡的數排序(預設從大到小,使用「

//優先順序佇列的宣告方式

//int為預設方式

priority_queue i;

priority_queue d;

//最常用的宣告方式

priority_queue q;

//node是乙個結構體

//結構體裡過載了『

priority_queue

,greater > q;

//不需要#include標頭檔案

//注意後面兩個「>」不要寫在一起,「>>」是右移運算子

priority_queue

,less >q;

//優先順序佇列的基本操作

q.size();//返回q裡元素個數

q.empty();//返回q是否為空,空則返回1,否則返回0

q.push(k);//在q的末尾插入k

q.pop();//刪掉q的第乙個元素

q.top();//返回q的第乙個元素

q.back();//返回q的末尾元素

3.100w個數中找到最大的前k個數思想:從100w個數中取出k個元素構建小堆,再從原資料中取出資料和堆頂元素比較。若小,不管;若大,替換堆頂元素,如果不滿足小堆,則調整堆,直到n-k個元素全部比較完成。

#define m 100000

#define k 100

//向下調整成最小堆

void adjustdown(int parent, int* a )

if (a [child] < a[parent])

else

break;

}}void getkmaxnum(int

array, int top )

//建最小堆

for (int i = (k - 2) / 2; i >= 0;i--)

//取array裡面剩下的數和top裡面的首元素進行比較,如果比首元素大,則替換,然後再次調整成最小堆

for (int i = k; i < m; i++)

void print(int *top)}}

4.堆排序【公升序建大堆,降序建小堆】此處降序示例

class greater

};class less

else

break;

}}//排降序

void sortheap(vector

& arr)

//排序

int end=size-1;

while(end)

}

結語
你總說未來很美好,但卻不知道美好的前提是努力奮鬥!

資料結構專題之堆

堆 heap 是乙個可以被看成近似完全二叉樹的陣列。樹上的每乙個結點對應陣列的乙個元素。除了最底層外,該樹是完全充滿的,而且是從左到右填充。堆包括最大堆和最小堆 最大堆的每乙個節點 除了根結點 的值不大於其父節點 最小堆的每乙個節點 除了根結點 的值不小於其父節點。堆常見的操作 堆結構的乙個常見應用...

資料結構專題總結

這幾天主要學習以及了解了幾種資料結構,只能說是大概理解了其作用,和基本使用方法,但還不能具體靈活運用。這裡主要談談對這幾個知識點的理解 首先是棧和佇列,主要是做了幾個關於棧的題目,佇列知識要與其他知識一起用,現在還不能知道其具體作用和用法。棧是主要特點是先進先出,在c 中有專門的類庫,但我更習慣用陣...

資料結構專題

一.並查集 主要操作 1.合併兩個不相交集合 2.判斷兩個元素是否屬於同一集合 時間複雜度 o n n 其中 x 對於x 宇宙中原子數之和,x 不大於4,事實上,路經壓縮後的並查集的複雜度是乙個很小的常數。模板題 include includeusing namespace std for poj ...