1. 程式人生 > >最大最小堆的插入與刪除

最大最小堆的插入與刪除

/刪除操作的BUG已經修復 /
最大堆、最小堆是一種用可用陣列儲存,並模擬實現二叉樹的資料結構。
最大(小)堆具有以下的顯著性質:
●最大(小)堆是一棵樹,且是完全二叉樹。
●最大(小)堆是每個根節點都一定大(小)於等於其子節點。
●在具體的儲存時陣列的[0]位置存放一個哨兵元素用於插入時防止越界,且由於這是 一棵完全二叉樹,位於[i]的節點其對應的父節點剛好是[i/2]。
●這裡討論的是二叉堆,以下程式碼對應二叉堆的性質。

最大堆的例項
這裡寫圖片描述
最小堆的例項
這裡寫圖片描述

最大堆的刪除操作:
這裡寫圖片描述
最大堆的刪除每次是從堆中刪除最大的元素,即堆頂
刪除的基本步驟:
1、堆的size減一,用變數儲存堆的末尾元素(本圖中是30)
2、刪除堆頂,並上浮兩個節點中的較大的子節點補位。
3、判斷child指向的節點是否越界,沒有的話,進入下一層,並重復第二步。
4、將末尾元素補位上浮到parent指向的節點。

最小堆的刪除操作:
這裡寫圖片描述
最大堆的刪除每次是從堆中刪除最小的元素,即堆頂
刪除的基本步驟:
1、堆的size減一,用變數儲存堆的末尾元素(本圖中是30)
2、刪除堆頂,並上浮兩個節點中的較小的子節點補位。
3、判斷child指向的節點是否越界,沒有的話,進入下一層,並重復第二步。
4、將末尾元素補位上浮到parent指向的節點。

最大堆的插入操作:
這裡寫圖片描述
插入元素每次都從陣列末尾開始查詢查詢點:
1、若此時插入點不符合條件,則將插入點的父節點下沉。
2、判斷是否到頂(有哨兵在可以防住越界),沒有到頂繼續第一步。
3、找到插入點時插入。

最小堆的插入操作:
這裡寫圖片描述
插入元素每次都從陣列末尾開始查詢查詢點:
1、若此時插入點不符合條件,則將插入點的父節點下沉。
2、判斷是否到頂(有哨兵在可以防住越界),沒有到頂繼續第一步。
3、找到插入點時插入。

具體的程式碼

/*
時間:2015.7.18
名稱:哈夫曼樹
操作:二叉堆的建立(建構函式)、最大最小堆的插入、最大最小堆的刪除、判斷堆空、判斷堆滿
簡述:
*/
#include<iostream>
using namespace std;
const int MAX_DATA=10000;//堆的可容納的最大元素,當做首位的哨兵用
const int MIN_DATA = -10000;//堆的可容納的最小元素,當做首位的哨兵用
enum Type{ Maximum, Minimum };//分別代表最大最小堆
class Heap
{
private:
    int *data;      //存放堆中元素
int size; //堆的目前大小 int capacity;//堆的最大容量 Type type; //堆的具體型別 public: Heap() { int c, t; cout << "堆的最大容量為"; cin >> c; cout << "堆的型別為(1為最大堆,0為最小堆):"; cin >> t; size = c;//初始化是沒有元素 capacity = MAX_DATA;//設定容量為最大 if (t) type = Maximum;//設定堆的型別 else type = Minimum; data = new int[capacity + 1];//動態申請記憶體 if (type==Maximum) data[0] = MAX_DATA;//最大堆的0位置處放最大元素 else data[0] = MIN_DATA;//最大堆的0位置處放最小元素 //最大堆的元素輸入按照從大到小 //最小堆的元素輸入按照從小到大 for (int i = 1; i <= c; i++) cin >> data[i]; }; ~Heap() { delete[]data; }; //判斷堆是否滿 int isFull() { if (size == capacity) return 1; else return 0; } //判斷堆是否空 int isEmpty() { if (size == 0) return 1; else return 0; } //最大堆的插入 void insertMaxHeap() { int i,item; cout << "輸入插入的元素"; cin >> item; if (isFull()) { cout << "堆已滿" << endl; return; } i = size + 1; size++;//先指向陣列的末尾,size增加1是因為插入時增加了一個元素 for (; data[i/2] < item; i /= 2)//找到第一個比item大的元素時結束 { data[i] = data[i/2];//若沒有找到,則將上一層的元素挪到下一層 } data[i] = item;//找到插入點,插入item } //最小堆的插入 void insertMinHeap() { int i, item; cout << "輸入插入的元素"; cin >> item; if (isFull()) { cout << "堆已滿" << endl; return; } i = size + 1; size++; for (; data[i/2] > item; i /= 2)//找到第一個比item小的元素時結束 { data[i] = data[i / 2];//沒有找到則將上一層元素挪到下一層 } data[i] = item;//找到插入點,插入item } //最大堆的刪除 int deleteMaxHeap() { //原理如下:記錄並刪除最大元素,然後自頂向下上浮其較大的子節點 //上浮完畢後進入向下進入一層,最後將最小的元素補位上浮 if (isEmpty()) { size = 0; return MAX_DATA;//為空返回不可能的值 } int child=1, parent=1;//指向父節點和子節點的遊標 int max = data[1];//記錄最大值用於返回 int last = data[size--];//記錄末尾最小值,並且size減1 for (parent = 1; parent * 2 <= size; parent = child)//迴圈上浮子節點 { child = parent * 2;//child指向其子節點 if (child!=size)//有時只有一個子節點,這裡要防止越界 if (data[child] < data[child + 1])//child指向的是較大的子節點 child++; if (last<data[parent])//找到了min的插入點就代表上浮完畢,結束迴圈並插入 if (last>data[child]) break; else data[parent] = data[child];//沒有找到就繼續上浮 } data[parent] = last;//將末尾的最小值補位上浮 return max; } //最小堆的刪除 int deleteMinHeap() { //原理如下:記錄並刪除最小元素,然後自頂向下上浮其較小的子節點 //上浮完畢後進入向下進入一層,最後將最大的元素補位上浮 if (isEmpty()) { size = 0; return MIN_DATA;//為空返回不可能的值 } int child=1, parent=1;//指向父節點和子節點的遊標 int min = data[1];//記錄最小值用於返回 int last= data[size--];//記錄末尾最後一個值 for (parent=1; parent*2 <= size; parent = child)//迴圈上浮子節點 { child = parent * 2;//child指向其子節點 if (child!=size) if (data[child] > data[child + 1])//child指向的是較小的子節點 ++child; if (last > data[parent])//找到了last的插入點就代表上浮完畢,結束迴圈並插入 if (last < data[child]) break; else data[parent] = data[child];//沒有找到就繼續上浮 } data[child] = last;//將末尾的最大值補位上浮 return min; } //堆的檢視 void show() { int change = 1,tota1 = 0; for (int i = 1; i <= size; i++) { if (change == i) { cout << endl; change *= 2; } cout << data[i] << ' '; tota1++; } cout << endl; } }; int main() { //主函式是測試程式碼 Heap heap; heap.show(); //heap.insertMaxHeap(); heap.insertMinHeap(); heap.show(); //int i = heap.deleteMaxHeap(); int i = heap.deleteMinHeap(); heap.show(); return 0; }

相關推薦

插入刪除

/刪除操作的BUG已經修復 / 最大堆、最小堆是一種用可用陣列儲存,並模擬實現二叉樹的資料結構。 最大(小)堆具有以下的顯著性質: ●最大(小)堆是一棵樹,且是完全二叉樹。 ●最大(小)堆是每個根節點都一定大(小)於等於其子節點。 ●在具體的儲存時陣列

的建立 插入 刪除

操作 2個 是把 完全二叉樹 bsp 通過 函數 問題 .... 堆是完全二叉樹,完全二叉樹最大的特點就是 把數據儲存在數組裏 通過父子結點的關系來做 不用實際建樹 parent=leftchild/2; leftchild=2*parent 右就加1這兒指的是序號關

---實現插入刪除

堆 堆在優先順序佇列的各種實現中,是最高效的一種資料結構 假定在各個資料記錄(或元素)中存在一個能夠標識資料記錄(或元素)的資料項,並將依據該資料項對資料進行組織,則可資料項成為關鍵碼(key) 如果有一個關鍵碼的集合K = {k0 , k1 , k2

大堆,插入/刪除以及大堆的排序

先說一下最大堆如何排序:轉自:http://www.cnblogs.com/luchen927/archive/2012/03/08/2381446.html 最大堆和最小堆在演算法中也有運用。比如用最大堆求N個數中前K個最小的數,用最小堆求N個數中前K個最大的數。你懂了嗎

STL - priority_queue

常用函數 cnblogs () mes color pre pac clas 常用 //添加頭文件#include<queue> using namespace std; 最大堆實現: 優先輸出大數據 priority_queue<Type, Cont

整理 & heapq大堆

參考資料: 關於堆排序的演算法參考:https://www.cnblogs.com/chengxiao/p/6129630.html 關於堆排序的視訊演示: https://www.bilibili.com/video/av18980178/ 對於一個數組,可以使用min()和max()

【劍指offer】資料流中的中位數(實現)

題目描述 如何得到一個數據流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用Insert()方法讀取資料流,使用GetMedian()方法獲取當前讀取資料的中位

C++中min_element()max_element()(取容器中的值)

min_element 和 max_element 標頭檔案:#include<algorithm> 作用:返回容器中最小值和最大值的指標。max_element(first,end,cmp);其中cmp為可選擇引數! 例1 #include<ios

似然估計(MLE)二乘估計(LSE)的區別

最大似然估計與最小二乘估計的區別 標籤(空格分隔): 概率論與數理統計 最小二乘估計 對於最小二乘估計來說,最合理的引數估計量應該使得模型能最好地擬合樣本資料,也就是估計值與觀測值之差的平方和最小。 設Q表示平方誤差,Yi表示估計值,Ŷ

javascript實現二叉樹排序,前中後序遍歷,值特定值查詢以及刪除節點

 函式執行時,會產生一個棧用來存放資料,當遍歷到目的節點時,操作結束以後,就會自動執行出棧操作,所以每次執行完畢指標都會自動跳回根節點。可以在開發者模式裡打斷點看到全過程。 <!DOCTYPE html> <html> <head> <me

[資料結構演算法]二叉樹查詢結點和

由於BST的屬性,所以查詢最大與最小值的程式碼幾乎是微不足道的事情。人們總可以在根節點左子樹的最左側的節點上找到BST內的最小值,另一方面,則會在跟節點有字數的最右側節點上找到BST內的最大值。

從一個集合中查詢的N個元素——Python heapq 資料結構

Top N問題在搜尋引擎、推薦系統領域應用很廣, 如果用我們較為常見的語言,如C、C++、Java等,程式碼量至少也得五行,但是用Python的話,只用一個函式就能搞定,只需引入heapq(堆佇列)這個資料結構即可。今天偶然看到這個庫,特意記下之。 先看一個例子: 複製

---陣列的實現

最大堆是我在看浙大陳越老師的資料結構視訊學到的,用的陣列實現的如何描述堆呢?用我自己的話說就是:根是這顆樹最大的值,每個   根節點都比    左右子節點的值大, 對左右子樹仍然成立; 那麼最小堆呢正好相反:根是這顆樹的最小的值, 每個  根節點都比左右子節點的值小, 同樣對

二叉搜尋樹:大堆的建立,插入刪除

前面我們講到棧和佇列的時候,這兩種資料結構都是按時間的先後順序來排列,如棧是按先進後出(FILO),後入先出的原則排列。而佇列是按先進先出(FIFO)的原則排序。但有時候按這種時間原則的資料結構不能滿足使用者的一些需求,例如CPU需要執行程式的優先級別,很多時候不能靠時間順序

【圖論】流之EK演算法Dinic演算法及費用

最大流: 給出一張網路圖,並指定源點和終點,每條邊都有它的容量,起點有著無限的流量,求從源點到經過的所有路徑的最終到達匯點的最大流量和。對於同一個節點,流入的流量之和和流出的流量之和相同,即假如結點1有12流量流入結點2,結點2分別有8流量流入結點3,4流量流入結點4,這種

均值濾波,中值濾波,值濾波

fin proc repeat 效果 mod ava rom static 包含 http://blog.csdn.net/fastbox/article/details/7984721 討論如何使用卷積作為數學工具來處理圖像,實現圖像的濾波,其方法包含以下幾種,均值 濾波

Tingq 模糊查詢 共多少條數據 、平均、求和值 升、降序

string sys post nat sender type asp idt acl 頁面代碼 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs" Inherits="

MT【61】含參數二次函數

tco pla 最大 back inline 我們 最小 但是 alt 評:此類題目在高考中作為壓軸題也曾考過,一般通性通法都如上面的做法,但是我們如果可以站在包絡的角度,很多問題將變得很清晰:MT【61】含參數二次函數最大最小值

分治算法 ------數組的

nbsp span 最大 技術分享 www images 如果 chinese 1-1 終於 找到課程鏈接了,太贊了,屈婉玲老師真的太厲害了! http://www.chinesemooc.org/kvideo.php?do=course_progress&kvid

求二叉樹深度

als 最小 log root roo null mat dep tde 1.求二叉樹最大深度 public int maxDepth(TreeNode root) { if(root==null){ return 0;