complete the coding of complete binary heap, with all tests passed.
This commit is contained in:
93
thu_dsa/chp10/CompleteBinaryHeap.h
Normal file
93
thu_dsa/chp10/CompleteBinaryHeap.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#ifndef COMPLETEBINARYHEAP_H_
|
||||
#define COMPLETEBINARYHEAP_H_
|
||||
|
||||
#include "../chp2/Vector.h"
|
||||
#include "PriorityQueue.h"
|
||||
|
||||
#define INHEAP(i) ((i >= 0) && (i < getSize()))
|
||||
#define PARENT(i) ((i-1) >> 1)
|
||||
#define LCHILD(i) ((i << 1) + 1)
|
||||
#define RCHILD(i) ((i << 1) + 2)
|
||||
#define HASPARENT(i) INHEAP(PARENT(i))
|
||||
#define HASLCHILD(i) INHEAP(LCHILD(i))
|
||||
#define HASRCHILD(i) INHEAP(RCHILD(i))
|
||||
#define LASTINTERNAL PARENT(size() - 1)
|
||||
|
||||
template <typename K, typename V>
|
||||
class CBHeap: public Vector<entry<K, V>>, public PriorityQueue<K, V>{
|
||||
protected:
|
||||
//internal methods
|
||||
void percolate_down(int pos);
|
||||
void percolate_up(int pos);
|
||||
int proper_parent(int pos);
|
||||
|
||||
public:
|
||||
//constructor
|
||||
CBHeap() = default;
|
||||
CBHeap(entry<K, V>* src, int n);
|
||||
|
||||
int size() { return getSize(); }
|
||||
bool empty(){ return size() == 0; }
|
||||
void insert(entry<K, V> e);
|
||||
void insert(K key, V value) { insert(entry<K, V>(key, value)); }
|
||||
entry<K, V> getMax() { return _elem[0]; }
|
||||
entry<K, V> delMax();
|
||||
|
||||
};
|
||||
|
||||
//internal methods
|
||||
|
||||
template <typename K, typename V>
|
||||
int CBHeap<K, V>::proper_parent(int pos){
|
||||
if (!HASLCHILD(pos)) return pos;
|
||||
if (!HASRCHILD(pos)) return get(pos) >= get(LCHILD(pos)) ? pos : LCHILD(pos);
|
||||
int proper = get(pos) >= get(LCHILD(pos)) ? pos : LCHILD(pos);
|
||||
return get(proper) >= get(RCHILD(pos)) ? proper : RCHILD(pos);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void CBHeap<K, V>::percolate_down(int pos){
|
||||
entry<K, V> tmp = get(pos);
|
||||
for(int p = proper_parent(pos); p != pos; p = proper_parent(pos)){
|
||||
get(pos) = get(p);
|
||||
pos = p;
|
||||
get(pos) = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void CBHeap<K, V>::percolate_up(int pos){
|
||||
entry<K, V> tmp = get(pos);
|
||||
while(HASPARENT(pos)){
|
||||
if(get(PARENT(pos)) >= tmp) break;
|
||||
|
||||
get(pos) = get(PARENT(pos));
|
||||
pos = PARENT(pos);
|
||||
}
|
||||
get(pos) = tmp;
|
||||
}
|
||||
|
||||
//public methods
|
||||
|
||||
template <typename K, typename V>
|
||||
CBHeap<K, V>::CBHeap(entry<K, V>* src, int n){
|
||||
copyfrom(src, 0, n);
|
||||
for (int ix = LASTINTERNAL; ix >= 0; --ix)
|
||||
percolate_down(ix);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void CBHeap<K, V>::insert(entry<K, V> e){
|
||||
push_back(e);
|
||||
percolate_up(getSize() - 1);
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
entry<K, V> CBHeap<K, V>::delMax(){
|
||||
entry<K, V> max = get(0);
|
||||
_elem[0] = _elem[_size-- - 1];
|
||||
percolate_down(0);
|
||||
return max;
|
||||
}
|
||||
|
||||
#endif
|
||||
32
thu_dsa/chp10/PriorityQueue.h
Normal file
32
thu_dsa/chp10/PriorityQueue.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef PRIORITYQUEUE_H_
|
||||
#define PRIORITYQUEUE_H_
|
||||
|
||||
template <typename K, typename V>
|
||||
class entry{
|
||||
public:
|
||||
K key;
|
||||
V value;
|
||||
|
||||
//constructor
|
||||
entry() = default;
|
||||
entry(K k, V v) : key(k), value(v) {}
|
||||
|
||||
//overload operator
|
||||
bool operator==(entry<K, V> const e) { return key == e.key; }
|
||||
bool operator!=(entry<K, V> const e) { return key != e.key; }
|
||||
bool operator>(entry<K, V> const e) { return key > e.key; }
|
||||
bool operator<(entry<K, V> const e) { return key < e.key; }
|
||||
bool operator>=(entry<K, V> const e) { return (key > e.key) || (key == e.key); }
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
class PriorityQueue{
|
||||
virtual int size() = 0;
|
||||
virtual bool empty() = 0;
|
||||
virtual entry<K, V> getMax() = 0;
|
||||
virtual entry<K, V> delMax() = 0;
|
||||
virtual void insert(K key, V value) = 0; //duplicate keys are allowed
|
||||
virtual void insert(entry<K, V> e) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
64
thu_dsa/chp10/testHeap.cpp
Normal file
64
thu_dsa/chp10/testHeap.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "CompleteBinaryHeap.h"
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
void test_insert();
|
||||
void test_max();
|
||||
void test_heapify();
|
||||
|
||||
int main(){
|
||||
cout << "Running tests" << endl;
|
||||
|
||||
test_heapify();
|
||||
test_insert();
|
||||
test_max();
|
||||
|
||||
cout << "All tests passed." << endl;
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_heapify(){
|
||||
int keys[] = { 5, 4, 7, 9, 1, 2, 8, 3, 6, 0 };
|
||||
int results[] = { 9, 6, 8, 5, 1, 2, 7, 3, 4, 0};
|
||||
entry<int, int> src[10];
|
||||
for (int ix = 0; ix != 10; ++ix)
|
||||
src[ix] = entry<int, int>(keys[ix], 0);
|
||||
CBHeap<int, int> heap(src, 10);
|
||||
assert(heap.size() == 10);
|
||||
for (int ix = 0; ix != 10; ++ix) {
|
||||
assert(heap[ix].key == results[ix]);
|
||||
}
|
||||
}
|
||||
|
||||
void test_insert(){
|
||||
int keys[] = { 5, 4, 7, 9, 1, 2, 8, 3, 6, 0 };
|
||||
int results[] = { 9, 7, 8, 6, 1, 2, 5, 3, 4, 0 };
|
||||
CBHeap<int, int> heap;
|
||||
for(int ix = 0; ix != 10; ++ix){
|
||||
assert(heap.size() == ix);
|
||||
heap.insert(entry<int, int>(keys[ix], 0));
|
||||
}
|
||||
for (int ix = 0; ix != 10; ++ix)
|
||||
assert(heap[ix].key == results[ix]);
|
||||
}
|
||||
|
||||
void test_max(){
|
||||
int keys[] = { 5, 4, 7, 9, 1, 2, 8, 3, 6, 0 };
|
||||
entry<int, int> src[10];
|
||||
for (int ix = 0; ix != 10; ++ix)
|
||||
src[ix] = entry<int, int>(keys[ix], 0);
|
||||
CBHeap<int, int> heap(src, 10);
|
||||
for (int ix = 0; ix != 10; ++ix) {
|
||||
assert(heap.size() == 10 - ix);
|
||||
assert(heap.getMax().key == 9 - ix);
|
||||
assert(heap.delMax().key == 9 - ix);
|
||||
/*
|
||||
for (int jx = 0; jx != 9 - ix; ++jx)
|
||||
cout << heap[jx].key << " ";
|
||||
cout << endl;
|
||||
*/
|
||||
}
|
||||
}
|
||||
14
thu_dsa/hash.md
Normal file
14
thu_dsa/hash.md
Normal file
@@ -0,0 +1,14 @@
|
||||
Conclusions on Hashing
|
||||
======================
|
||||
|
||||
## 散列函数的设计
|
||||
散列函数无非一个映射,其功能无非是将词条空间中的元素映射到散列表地址空间,其中前者远远大于后者,所以绝不可能是一个单射
|
||||
好的散列函数
|
||||
- 确定性:同一关键码总是被映射到同一地址
|
||||
- 快速
|
||||
- 满射:充分利用散列空间
|
||||
- 均匀:避免汇聚clustering。
|
||||
散列函数
|
||||
- 除余法
|
||||
- MAD法
|
||||
- 折叠法
|
||||
Reference in New Issue
Block a user