最大堆
template<typename Item>
class MaxHeap{
private:
Item *data;
int count;
int capacity;
void shiftUp(int k){
while( k > 1 && data[k/2] < data[k] ){
swap( data[k/2], data[k] );
k /= 2;
}
}
void shiftDown(int k){
while( 2*k <= count ){
int j = 2*k;
if( j+1 <= count && data[j+1] > data[j] ) j ++;
if( data[k] >= data[j] ) break;
swap( data[k] , data[j] );
k = j;
}
}
public:
MaxHeap(int capacity){
data = new Item[capacity+1];
count = 0;
this->capacity = capacity;
}
MaxHeap(Item arr[], int n){
data = new Item[n+1];
capacity = n;
for( int i = 0 ; i < n ; i ++ )
data[i+1] = arr[i];
count = n;
for( int i = count/2 ; i >= 1 ; i -- )
shiftDown(i);
}
~MaxHeap(){
delete[] data;
}
int size(){
return count;
}
bool isEmpty(){
return count == 0;
}
void insert(Item item){
assert( count + 1 <= capacity );
data[count+1] = item;
shiftUp(count+1);
count ++;
}
Item extractMax(){
assert( count > 0 );
Item ret = data[1];
swap( data[1] , data[count] );
count --;
shiftDown(1);
return ret;
}
Item getMax(){
assert( count > 0 );
return data[1];
}
};
heap sort
template<typename T>
void heapSort2(T arr[], int n){
MaxHeap<T> maxheap = MaxHeap<T>(arr,n);
for( int i = n-1 ; i >= 0 ; i-- )
arr[i] = maxheap.extractMax();
}
template<typename T>
void heapSort1(T arr[], int n){
MaxHeap<T> maxheap = MaxHeap<T>(n);
for( int i = 0 ; i < n ; i ++ )
maxheap.insert(arr[i]);
for( int i = n-1 ; i >= 0 ; i-- )
arr[i] = maxheap.extractMax();
}
二分搜索 binary sort
// 用递归的方式写二分查找法
template<typename T>
int __binarySearch2(T arr[], int l, int r, T target){
if( l > r )
return -1;
int mid = (l+r)/2;
if( arr[mid] == target )
return mid;
else if( arr[mid] > target )
return __binarySearch2(arr, 0, mid-1, target);
else
return __binarySearch2(arr, mid+1, r, target);
}
二分搜索树
template <typename Key, typename Value>
class BST{
private:
struct Node{
Key key;
Value value;
Node *left;
Node *right;
Node(Key key, Value value){
this->key = key;
this->value = value;
this->left = this->right = NULL;
}
Node(Node *node){
this->key = node->key;
this->value = node->value;
this->left = node->left;
this->right = node->right;
}
};
Node *root;
int count;
public:
BST(){
root = NULL;
count = 0;
}
~BST(){
destroy( root );
}
int size(){
return count;
}
bool isEmpty(){
return count == 0;
}
void insert(Key key, Value value){
root = insert(root, key, value);
}
bool contain(Key key){
return contain(root, key);
}
Value* search(Key key){
return search( root , key );
}
// 前序遍历
void preOrder(){
preOrder(root);
}
// 中序遍历
void inOrder(){
inOrder(root);
}
// 后序遍历
void postOrder(){
postOrder(root);
}
// 层序遍历
void levelOrder(){
queue<Node*> q;
q.push(root);
while( !q.empty() ){
Node *node = q.front();
q.pop();
cout<<node->key<<endl;
if( node->left )
q.push( node->left );
if( node->right )
q.push( node->right );
}
}
// 寻找最小的键值
Key minimum(){
assert( count != 0 );
Node* minNode = minimum( root );
return minNode->key;
}
// 寻找最大的键值
Key maximum(){
assert( count != 0 );
Node* maxNode = maximum(root);
return maxNode->key;
}
// 从二叉树中删除最小值所在节点
void removeMin(){
if( root )
root = removeMin( root );
}
// 从二叉树中删除最大值所在节点
void removeMax(){
if( root )
root = removeMax( root );
}
// 从二叉树中删除键值为key的节点
void remove(Key key){
root = remove(root, key);
}
private:
// 向以node为根的二叉搜索树中,插入节点(key, value)
// 返回插入新节点后的二叉搜索树的根
Node* insert(Node *node, Key key, Value value){
if( node == NULL ){
count ++;
return new Node(key, value);
}
if( key == node->key )
node->value = value;
else if( key < node->key )
node->left = insert( node->left , key, value);
else // key > node->key
node->right = insert( node->right, key, value);
return node;
}
// 查看以node为根的二叉搜索树中是否包含键值为key的节点
bool contain(Node* node, Key key){
if( node == NULL )
return false;
if( key == node->key )
return true;
else if( key < node->key )
return contain( node->left , key );
else // key > node->key
return contain( node->right , key );
}
// 在以node为根的二叉搜索树中查找key所对应的value
Value* search(Node* node, Key key){
if( node == NULL )
return NULL;
if( key == node->key )
return &(node->value);
else if( key < node->key )
return search( node->left , key );
else // key > node->key
return search( node->right, key );
}
// 对以node为根的二叉搜索树进行前序遍历
void preOrder(Node* node){
if( node != NULL ){
cout<<node->key<<endl;
preOrder(node->left);
preOrder(node->right);
}
}
// 对以node为根的二叉搜索树进行中序遍历
void inOrder(Node* node){
if( node != NULL ){
inOrder(node->left);
cout<<node->key<<endl;
inOrder(node->right);
}
}
// 对以node为根的二叉搜索树进行后序遍历
void postOrder(Node* node){
if( node != NULL ){
postOrder(node->left);
postOrder(node->right);
cout<<node->key<<endl;
}
}
void destroy(Node* node){
if( node != NULL ){
destroy( node->left );
destroy( node->right );
delete node;
count --;
}
}
// 在以node为根的二叉搜索树中,返回最小键值的节点
Node* minimum(Node* node){
if( node->left == NULL )
return node;
return minimum(node->left);
}
// 在以node为根的二叉搜索树中,返回最大键值的节点
Node* maximum(Node* node){
if( node->right == NULL )
return node;
return maximum(node->right);
}
// 删除掉以node为根的二分搜索树中的最小节点
// 返回删除节点后新的二分搜索树的根
Node* removeMin(Node* node){
if( node->left == NULL ){
Node* rightNode = node->right;
delete node;
count --;
return rightNode;
}
node->left = removeMin(node->left);
return node;
}
// 删除掉以node为根的二分搜索树中的最大节点
// 返回删除节点后新的二分搜索树的根
Node* removeMax(Node* node){
if( node->right == NULL ){
Node* leftNode = node->left;
delete node;
count --;
return leftNode;
}
node->right = removeMax(node->right);
return node;
}
// 删除掉以node为根的二分搜索树中键值为key的节点
// 返回删除节点后新的二分搜索树的根
Node* remove(Node* node, Key key){
if( node == NULL )
return NULL;
if( key < node->key ){
node->left = remove( node->left , key );
return node;
}
else if( key > node->key ){
node->right = remove( node->right, key );
return node;
}
else{ // key == node->key
if( node->left == NULL ){
Node *rightNode = node->right;
delete node;
count --;
return rightNode;
}
if( node->right == NULL ){
Node *leftNode = node->left;
delete node;
count--;
return leftNode;
}
// node->left != NULL && node->right != NULL
Node *successor = new Node(minimum(node->right));
count ++;
successor->right = removeMin(node->right);
successor->left = node->left;
delete node;
count --;
return successor;
}
}
};
void shuffle( int arr[], int n ){
srand( time(NULL) );
for( int i = n-1 ; i >= 0 ; i -- ){
int x = rand()%(i+1);
swap( arr[i] , arr[x] );
}
}
并查集union find
parent 指针
namespace UF2{
class UnionFind{
private:
int* parent;
int count;
public:
UnionFind(int count){
parent = new int[count];
this->count = count;
for( int i = 0 ; i < count ; i ++ )
parent[i] = i;
}
~UnionFind(){
delete[] parent;
}
int find(int p){
assert( p >= 0 && p < count );
while( p != parent[p] )
p = parent[p];
return p;
}
bool isConnected( int p , int q ){
return find(p) == find(q);
}
void unionElements(int p, int q){
int pRoot = find(p);
int qRoot = find(q);
if( pRoot == qRoot )
return;
parent[pRoot] = qRoot;
}
};
}
基于size的优化
namespace UF3{
class UnionFind{
private:
int* parent;
int* sz; // sz[i]表示以i为根的集合中元素个数
int count;
public:
UnionFind(int count){
parent = new int[count];
sz = new int[count];
this->count = count;
for( int i = 0 ; i < count ; i ++ ){
parent[i] = i;
sz[i] = 1;
}
}
~UnionFind(){
delete[] parent;
delete[] sz;
}
int find(int p){
assert( p >= 0 && p < count );
while( p != parent[p] )
p = parent[p];
return p;
}
bool isConnected( int p , int q ){
return find(p) == find(q);
}
void unionElements(int p, int q){
int pRoot = find(p);
int qRoot = find(q);
if( pRoot == qRoot )
return;
if( sz[pRoot] < sz[qRoot] ){
parent[pRoot] = qRoot;
sz[qRoot] += sz[pRoot];
}
else{
parent[qRoot] = pRoot;
sz[pRoot] += sz[qRoot];
}
}
};
}
基于层次rank的优化
namespace UF3{
class UnionFind{
private:
int* parent;
int* rank; // rank[i]表示以i为根的集合所表示的树的层数
int count;
public:
UnionFind(int count){
parent = new int[count];
rank = new int[count];
this->count = count;
for( int i = 0 ; i < count ; i ++ ){
parent[i] = i;
rank[i] = 1;
}
}
~UnionFind(){
delete[] parent;
delete[] rank;
}
int find(int p){
assert( p >= 0 && p < count );
while( p != parent[p] )
p = parent[p];
return p;
}
bool isConnected( int p , int q ){
return find(p) == find(q);
}
void unionElements(int p, int q){
int pRoot = find(p);
int qRoot = find(q);
if( pRoot == qRoot )
return;
if( rank[pRoot] < rank[qRoot] ){
parent[pRoot] = qRoot;
}
else if( rank[qRoot] < rank[pRoot]){
parent[qRoot] = pRoot;
}
else{ // rank[pRoot] == rank[qRoot]
parent[pRoot] = qRoot;
rank[qRoot] += 1;
}
}
};
}
图论
稀疏图--邻接表
// 稀疏图 - 邻接表
class SparseGraph{
private:
int n, m;
bool directed;
vector<vector<int>> g;
public:
SparseGraph( int n , bool directed ){
this->n = n;
this->m = 0;
this->directed = directed;
for( int i = 0 ; i < n ; i ++ )
g.push_back( vector<int>() );
}
~SparseGraph(){
}
int V(){ return n;}
int E(){ return m;}
void addEdge( int v, int w ){
assert( v >= 0 && v < n );
assert( w >= 0 && w < n );
g[v].push_back(w);
if( v != w && !directed )
g[w].push_back(v);
m ++;
}
bool hasEdge( int v , int w ){
assert( v >= 0 && v < n );
assert( w >= 0 && w < n );
for( int i = 0 ; i < g[v].size() ; i ++ )
if( g[v][i] == w )
return true;
return false;
}
};
稠密图--邻接矩阵
// 稠密图 - 邻接矩阵
class DenseGraph{
private:
int n, m;
bool directed;
vector<vector<bool>> g;
public:
DenseGraph( int n , bool directed ){
this->n = n;
this->m = 0;
this->directed = directed;
for( int i = 0 ; i < n ; i ++ )
g.push_back( vector<bool>(n, false) );
}
~DenseGraph(){
}
int V(){ return n;}
int E(){ return m;}
void addEdge( int v , int w ){
assert( v >= 0 && v < n );
assert( w >= 0 && w < n );
if( hasEdge( v , w ) )
return;
g[v][w] = true;
if( !directed )
g[w][v] = true;
m ++;
}
bool hasEdge( int v , int w ){
assert( v >= 0 && v < n );
assert( w >= 0 && w < n );
return g[v][w];
}
};