專題主要內容
堆的概念、性質堆的概念堆的建立
堆的插入&刪除
堆的應用
堆(heap),這裡所說的堆是資料結構中的堆,而不是記憶體模型中的堆。堆通常是乙個可以被看做一棵樹,它滿足下列性質:
[性質一]堆中任意節點的值總是不大於(不小於)其子節點的值;
[性質二]堆總是一棵完全樹。
將任意節點不大於其子節點的堆叫做小堆或小根堆,而將任意節點不小於其子節點的堆叫做大堆或大根堆。常見的堆有二叉堆、左傾堆、斜堆、二項堆、斐波那契堆等等。
二叉堆
二叉堆一般都通過」陣列」來實現。陣列實現的二叉堆,父節點和子節點的位置存在一定的關係。有時候,我們將」二叉堆的第乙個元素」放在陣列索引0的位置,有時候放在1的位置。當然,它們的本質一樣(都是二叉堆),只是實現上稍微有一丁點區別。二叉堆性質
在前面,我們已經了解到:」最大堆」和」最小堆」是對稱關係。這也意味著,了解其中之一即可。本節的**解析是以」最大堆」來進行介紹的。
二叉堆的核心是」新增節點」和」刪除節點」,理解這兩個演算法,二叉堆也就基本掌握了。下面對它們進行介紹。
建立新增&刪除
堆操作相關參考**
heap.h
heap.c//定義堆結構(動態線性表實現)
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);
!!!經典練習【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");
}
實現堆建立,插入及刪除解答:1. 實現堆建立,插入及刪除在實現堆的建立時,我們以大堆為例,大堆的建立需要自上向下調整堆,建立堆的時間複雜度為o(log2 n)。優先順序佇列
100w個數中找到最大的前k個數
堆排序
2.優先順序佇列優先順序佇列的底層為堆,是一種特殊的佇列,這種佇列會自動的把佇列裡的數排序(預設從大到小,使用「//向下調整
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)
3.100w個數中找到最大的前k個數思想:從100w個數中取出k個元素構建小堆,再從原資料中取出資料和堆頂元素比較。若小,不管;若大,替換堆頂元素,如果不滿足小堆,則調整堆,直到n-k個元素全部比較完成。//優先順序佇列的宣告方式
//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的末尾元素
4.堆排序【公升序建大堆,降序建小堆】此處降序示例#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)}}
結語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 ...