本練習主要做了幾個工作:
1.給定乙個陣列來初始化二叉堆,第一種方法是通過不斷插入,時間複雜度是o(nlgn),第二種方法是先把陣列填入二叉堆,再從下標為h->size/2的節點開始下濾,這是因為只有下標小於為h->size/2才有孩子,從而可以用線性時間完成二叉堆的初始化。
2.二叉堆的下濾和上濾,對二叉堆關鍵字的操作諸如刪除最小,增加某關鍵字值,減少某關鍵字值等會可能改變堆性質的操作,必須用上濾和下濾來保證二叉堆的性質,比如增加了某關鍵字的值,該關鍵字可能往下走,因此對該節點採用下濾,與之相反,減少時則要上濾。
3.刪除操作是把要刪除關鍵字的位置先求出來,用二叉樹最後乙個數字來覆蓋這個位置的值,並使堆的大小減1,此時要比較要刪除的值與該位置新值,根據大小關係來採用上濾或下濾。
4.給定乙個x,用o(k)的時間求出小於x的關鍵字,主要用了層序遍歷的思想,從上往下一層層地走,遇到比x小的把它兒子入棧,迴圈至棧空。
5.用至多3n/4的時間找出任意乙個關鍵字x的位置,主要是先比較倒數第二層的節點,看x和這層節點的關係,若x大於這層所有的節點,這只需要檢查所有葉節點,而葉節點的數量不會超過n/2,倒數第二層的節點不會超過n/4,故此時總的比較次數不會超過3n/4。若x小於這層所有的節點,則只需要檢查剩下的n/2個節點即可,滿足題意。
// youxianduilie_lianxi.cpp : 定義控制台應用程式的入口點。//#include "stdafx.h"
#include#includeusing namespace std;
struct heapstruct;
typedef struct heapstruct *priorityqueue;
#define mindata -65536
#define notexist -1
struct heapstruct
;priorityqueue initialize(int maxelement) //初始化堆
bool isfull(priorityqueue h)
void insert(int x, priorityqueue h)
for (i = ++h->size; h->elements[i / 2] > x; i /= 2) //迴圈,在size+1的位置建立乙個空穴,
h->elements[i] = h->elements[i / 2]; //通過x不斷與其父節點比較,空穴不斷上移,直到父節點小於x;
h->elements[i] = x; //此時i的值就是x所插入的位置。
}priorityqueue initbyinsert(int maxelement,const int given,int num)
void percdown(priorityqueue h, int i) //下濾操作
h->elements[i] = tmp;
}void percup(priorityqueue h, int i) //上濾操作跟下濾操作基本是對偶的
h->elements[i] = tmp;
}priorityqueue initbygiven(int maxelement, const int given, int num)
int deletemin(priorityqueue h) //刪除並返回最小值
minelement = h->elements[1]; //最小的在堆頂
lastelement = h->elements[h->size--]; //刪除後size-1;
h->elements[1] = lastelement; //堆頂的元素取走以後,留下乙個空穴,把堆的最後乙個元素放在堆頂上,對其進行下濾即可。
percdown(h, 1);
return minelement;
}void delete(priorityqueue h, int key) //直接刪除
void rewrite(int oldkey, int newkey, priorityqueue h)
void lessthan(int x, priorityqueue h) //用o(k)時間列印出堆中小於x的數
else
reme.pop();
} }}int quickfind(priorityqueue h, int x)
for (int i = h->size / 2; i > 0; i--) //如果上面在葉節點檢查出來了就不會執這個迴圈
return notexist;
}void print(priorityqueue h)
int main()
; //priorityqueue h=initbyinsert(100, given, 15);
priorityqueue h = initbygiven(100, given, 15);
print(h);
//lessthan(6, h);
cout << quickfind(h, 12);
//int min = deletemin(h);
//cout << min << endl;
//print(h);
//delete(h, 3);
//print(h);
//rewrite(2,77,h);
//print(h);
while (1);
return 0;
}
3110 二叉堆練習3
時間限制 3 s 空間限制 128000 kb 題目等級 gold description 給定n n 500,000 和n個整數 較有序 將其排序後輸出。輸入描述 input description n和n個整數 輸出描述 output description n個整數 公升序 樣例輸入 samp...
建立二叉堆 STL練習
算是對stl的一道練習題 思想 1.建立向量a,輸入測試資料 2.基於陣列下標,判斷當前堆頂是否已滿足要求 code include include include include using namespace std 傳入陣列a和下標i,i的左右子樹都滿足最大堆的性質,函式將a整體調整為最大堆 ...
3110 二叉堆練習3
時間限制 3 s 空間限制 128000 kb 題目等級 gold 題解檢視執行結果 給定n n 500,000 和n個整數 較有序 將其排序後輸出。輸入描述 input description n和n個整數 輸出描述 output description n個整數 公升序 樣例輸入 sample ...