#ifndef __BASE_H__
#define __BASE_H__
#include <iostream>
#include "binomial heap.h"
using namespace std;
/*********************************stack**********************************/
template<class node>
class stack
{
public:
stack(int n);
~stack();
private:
node *_s;
int _size;
int _height;
public:
int height(){return _height;}
void empty(){_height = 0;}
bool push(const node& nd);
bool pop(node& nd);
void top(node& nd){nd = _s[_height-1];}
};
template <class node>
stack<node>::stack(int n)
{
_s = new node[n];
_size = n;
_height = 0;
}
template <class node>
stack<node>::~stack()
{
delete _s;
}
template <class node>
bool stack<node>::push(const node& nd)
{
if (_height >= _size)return false;
_s[_height++] = nd;
return true;
}
template <class node>
bool stack<node>::pop(node& nd)
{
if (_height <= 0)return false;
nd = _s[--_height];
return true;
}
/**********************************queue*********************************/
template<class node>
class queue
{
public:
queue(int n);
~queue();
private:
node *_q;
int _size;
int _head;
int _tail;
public:
bool inqueue(const node &nd);
bool dequeue(node &nd);
int length(){return (_tail - _head + _size)%_size;}
void empty(){_head = _tail = 0;}
};
template<class node>
queue<node>::queue(int n)
{
_q = new node[n+1];
_size = n+1;
_head = _tail = 0;
}
template<class node>
queue<node>::~queue()
{
if (_q)
{
delete _q;
}
}
template<class node>
bool queue<node>::inqueue(const node &nd)
{
if ((_tail+1)%_size== _head)return false;
else
{
_q[_tail] = nd;
_tail = (_tail+1)%_size;
return true;
}
}
template<class node>
bool queue<node>::dequeue(node &nd)
{
if (_tail == _head)return false;
else
{
nd = _q[_head];
_head = (_head + 1)%_size;
return true;
}
}
/*********************************graph*************************************/
template <class vertex , class edge>
class graph
{
protected:
int _vcnt , _ecnt;
int _capacity;
int *_prt;
int *_dep;
int *_vist;
public:
graph(){_capacity = _vcnt = _ecnt = 0;_prt = _dep = _vist = NULL;}
virtual bool insert_vertex(vertex ver) = 0;
virtual bool insert_edge(int v1 , int v2 , edge ed) = 0;
virtual bool BFS(int s) = 0 ;
virtual bool DFS(int s) = 0 ;
virtual bool DFS_stack(int s) = 0 ;
virtual bool visit_result() = 0;
int num_vertex(){return _vcnt;}
int num_edge(){return _ecnt;}
};
/*******************************mtxgraph*************************************/
template <class vertex , class edge>
class mtxgraph : public graph<vertex , edge>
{
private:
vertex *_ver;
edge **_ed;
public:
mtxgraph();
mtxgraph(int n);
mtxgraph(mtxgraph& mg);
~mtxgraph();
virtual bool insert_vertex(vertex ver);
virtual bool insert_edge(int v1 , int v2 , edge ed);
virtual bool BFS(int s);
virtual bool DFS(int s);
virtual bool DFS_stack(int s);
virtual bool visit_result();
private:
void DFSrecur(int s , int *color , int time , int pare);
};
template <class vertex , class edge>
mtxgraph<vertex , edge>::mtxgraph()
{
_ver = NULL;
_ed = NULL;
}
template <class vertex , class edge>
mtxgraph<vertex , edge>::mtxgraph(int n)
{
_capacity = n;
_ver = new vertex[n];
_ed = new edge *[n];
_prt = new int[n];
_dep = new int[n];
_vist = new int[n];
for (int i = 0 ; i < n ; i++)
{
_ed[i] = new edge[n];
for (int j = 0 ; j < n ; j++)_ed[i][j] = 0;
_prt[i] = -1;
_dep[i] = -1;
}
}
template <class vertex , class edge>
mtxgraph<vertex , edge>::~mtxgraph()
{
if(_ver)
{
for (int i = 0 ; i < _capacity ; i++)delete _ed[i];
delete _ver;
delete _ed;
delete _prt;
delete _dep;
delete _vist;
}
}
template <class vertex , class edge>
mtxgraph<vertex , edge>::mtxgraph(mtxgraph& mg)
{
_capacity = mg._capacity;
_ver = new vertex[n];
_ed = new edge *[n];
_prt = new int[n];
_dep = new int[n];
_vist = new int[n];
for (int i = 0 ; i < n ; i++)
{
_ed[i] = new edge[n];
}
_vcnt = mg._vcnt;
_ecnt = mg._ecnt;
int vercap = _capacity * sizeof(vertex);
int edcap = _capacity * sizeof(edge);
int prtcap = _capacity * sizeof(int);
int depcap = _capacity * sizeof(int);
int vistcap = _capacity * sizeof(int);
memcpy(_ver , mg._ver , vercap);
memcpy(_ed , mg._ed , edcap);
memcpy(_prt , mg._prt , prtcap);
memcpy(_dep , mg._dep , depcap);
memcpy(_vist , mg._vist , vistcap);
for (int i = 0 ; i < _capacity ; i++)
{
memcpy(_ed[i] , mg._ed[i] , edcap)
}
}
template <class vertex , class edge>
bool mtxgraph<vertex , edge>::insert_vertex(vertex ver)
{
if (_vcnt >= _capacity)return false;
_ver[_vcnt++] = ver;
return true;
}
template <class vertex , class edge>
bool mtxgraph<vertex , edge>::insert_edge(int v1 , int v2 , edge ed)
{
if (v1 > _vcnt || v2 > _vcnt)return false;
_ed[v1][v2] = ed;
_ecnt++;
return true;
}
#define WHITE 0
#define GRAY 1
#define BLACK -1
template <class vertex , class edge>
bool mtxgraph<vertex , edge>::BFS(int s)
{
if(s >= _vcnt)return false;
int *color = new int[_vcnt];
int vistc = 0;
for (int i = 0 ; i < _vcnt ; i++)
{
color[i] = WHITE;
_dep[i] = -1;
_prt[i] = -1;
_vist[i] = -1;
}
color[s] = GRAY;
_dep[s] = 0;
_prt[s] = -1;
_vist[vistc++] = s;
queue<int> _queue(_vcnt);
_queue.inqueue(s);
while (_queue.length() != 0)
{
int nd;
_queue.dequeue(nd);
color[nd] = BLACK;
for (int i = 0 ; i < _vcnt ; i++)
{
if (_ed[nd][i] != 0 && color[i] == WHITE)
{
color[i] = GRAY;
_dep[i] = _dep[nd] + 1;
_vist[vistc++] = i;
_prt[i] = nd;
_queue.inqueue(i);
}
}
}
delete color;
return true;
}
template <class vertex , class edge>
bool mtxgraph<vertex , edge>::DFS(int s)
{
if(s >= _vcnt)return false;
int *color = new int[_vcnt];
int time = 0;
for (int i = 0 ; i < _vcnt ; i++)
{
color[i] = WHITE;
_dep[i] = -1;
_prt[i] = -1;
_vist[i] = -1;
}
color[s] = GRAY;
_dep[s] = 0;
_prt[s] = -1;
_vist[time] = s;
for (int i = 0 ; i < _vcnt ; i++)
{
if (_ed[s][i] != 0 && color[i] == WHITE)
{
color[i] = GRAY;
DFSrecur(i , color , ++time , s);
}
}
color[s] = BLACK;
delete color;
return true;
}
template <class vertex , class edge>
void mtxgraph<vertex , edge>::DFSrecur(int s , int *color , int time , int pare)
{
color[s] = GRAY;
_dep[s] = time;
_prt[s] = pare;
_vist[time] = s;
for ( int i = 0 ; i < _vcnt ; i++)
{
if (_ed[s][i] != 0 && color[i] == WHITE)
{
color[i] = GRAY;
DFSrecur(i , color , time+1 , s);
}
}
color[s] = BLACK;
}
template <class vertex , class edge>
bool mtxgraph<vertex , edge>::DFS_stack(int s)
{
if (s > _vcnt)return false;
int time = 0 , i;
int *color = new int[_vcnt];
for (i = 0 ; i < _vcnt ; i++)
{
color[i] = WHITE;
_dep[i] = -1;
_prt[i] = -1;
_prt[i] = -1;
}
color[s] = GRAY;
_prt[s] = -1;
_dep[s] = 0;
_vist[time++] = s;
stack<int> _stack(_vcnt);
_stack.push(s);
while(_stack.height() != 0)
{
int nd;
_stack.top(nd);
for(i = 0 ; i < _vcnt ; i++)
{
if (_ed[nd][i] != 0 && color[i] == WHITE)
{
_stack.push(i);
color[i] = GRAY;
_prt[i] = nd;
_dep[i] = time;
_vist[time++] = i;
break;
}
}
if (i == _vcnt)
{
int nd;
_stack.pop(nd);
color[nd] = BLACK;
}
}
return true;
}
template <class vertex , class edge>
bool mtxgraph<vertex , edge>::visit_result()
{
if (_vcnt <= 0)return false;
cout<<"visit result is:";
for (int i = 0 ; i < _vcnt ; i++)
{
if (_vist[i] != -1)cout<<_ver[_vist[i]]<<",";
}
return true;
}
/****************************************************************************/
template <class edge>
struct lnkgphnd
{
int _n;
edge _e;
struct lnkgphnd *next;
};
template <class vertex , class edge>
class lnkgraph : public graph<vertex , edge>
{
private:
vertex *_ver;
lnkgphnd<edge> **_nd;
public:
lnkgraph();
lnkgraph(int n);
lnkgraph(lnkgraph& mg);
~lnkgraph();
virtual bool insert_vertex(vertex ver);
virtual bool insert_edge(int v1 , int v2 , edge ed);
virtual bool BFS(int s);
virtual bool DFS(int s);
virtual bool DFS_stack(int s);
virtual bool visit_result();
lnkgraph<vertex , edge> *Prim(int n);
private:
void DFSrecur(int s , int *color , int time , int pare);
};
template <class vertex , class edge>
lnkgraph<vertex , edge>::lnkgraph()
{
_nd = NULL;
}
template <class vertex , class edge>
lnkgraph<vertex , edge>::lnkgraph(int n)
{
_capacity = n;
_ver = new vertex[n];
_nd = new lnkgphnd<edge>*[n];
_prt = new int[n];
_dep = new int[n];
_vist = new int[n];
for (int i = 0 ; i < n ; i++)
{
_nd[i] = NULL;
_prt[i] = -1;
_dep[i] = -1;
}
}
template <class vertex , class edge>
lnkgraph<vertex , edge>::~lnkgraph()
{
if(_nd)
{
for (int i = 0 ; i < _vcnt ; i++)
{
while(_nd[i])
{
lnkgphnd<edge> *nd = _nd[i];
_nd[i] = nd->next;
delete nd;
}
}
delete _ver;
delete _nd;
delete _prt;
delete _dep;
delete _vist;
}
}
template <class vertex , class edge>
lnkgraph<vertex , edge>::lnkgraph(lnkgraph& mg)
{
_capacity = mg._capacity;
_ver = new vertex[n];
_nd = new lnkgphnd<edge>*[n];
_prt = new int[n];
_dep = new int[n];
_vist = new int[n];
for (int i = 0 ; i < n ; i++)
{
_ed[i] = new edge[n];
}
_vcnt = mg._vcnt;
_ecnt = mg._ecnt;
int vercap = _capacity * sizeof(vertex);
int ndcap = _capacity * sizeof(int);
int prtcap = _capacity * sizeof(int);
int depcap = _capacity * sizeof(int);
int vistcap = _capacity * sizeof(int);
memcpy(_ver , mg._ver , vercap);
memcpy(_prt , mg._prt , prtcap);
memcpy(_dep , mg._dep , depcap);
memcpy(_vist , mg._vist , vistcap);
for (int i = 0 ; i < _vcnt ; i++)
{
lnkgphnd *nd = mg._nd[i];
lnkgphnd *dst = _nd[i];
lnkgphnd<edge> *ndd;
ndd = new lnkgphnd<edge>;
memcpy(ndd , nd , sizeof(lnkgphnd<edge>));
dst = ndd;
while(nd)
{
ndd = new lnkgphnd<edge>;
memcpy(ndd , nd , sizeof(lnkgphnd<edge>));
dst->next = ndd;
dst = ndd;
nd = nd->next;
}
dst->next = NULL;
}
}
template <class vertex , class edge>
bool lnkgraph<vertex , edge>::insert_vertex(vertex ver)
{
if (_vcnt >= _capacity)return false;
_ver[_vcnt] = ver;
_nd[_vcnt] = NULL;
_vcnt++;
return true;
}
template <class vertex , class edge>
bool lnkgraph<vertex , edge>::insert_edge(int v1 , int v2 , edge ed)
{
if (v1 >= _vcnt || v2 >= _vcnt)return false;
lnkgphnd<edge> *nd = new lnkgphnd<edge>;
nd->_n = v2;
nd->_e = ed;
nd->next = _nd[v1];
_nd[v1] = nd;
return true;
}
#define WHITE 0
#define GRAY 1
#define BLACK -1
template <class vertex , class edge>
bool lnkgraph<vertex , edge>::BFS(int s)
{
if(s >= _vcnt)return false;
int *color = new int[_vcnt];
int vistc = 0;
for (int i = 0 ; i < _vcnt ; i++)
{
color[i] = WHITE;
_dep[i] = -1;
_prt[i] = -1;
_vist[i] = -1;
}
color[s] = GRAY;
_dep[s] = 0;
_prt[s] = -1;
_vist[vistc++] = s;
queue<int> _queue(_vcnt);
_queue.inqueue(s);
while (_queue.length() != 0)
{
int nd;
_queue.dequeue(nd);
color[nd] = BLACK;
lnkgphnd<edge> *p = _nd[nd];
while(p)
{
if ( color[p->_n] == WHITE)
{
color[p->_n] = GRAY;
_dep[p->_n] = _dep[nd] + 1;
_vist[vistc++] = p->_n;
_prt[p->_n] = nd;
_queue.inqueue(p->_n);
}
p = p->next;
}
}
delete color;
return true;
}
template <class vertex , class edge>
bool lnkgraph<vertex , edge>::DFS(int s)
{
if(s >= _vcnt)return false;
int *color = new int[_vcnt];
int time = 0;
for (int i = 0 ; i < _vcnt ; i++)
{
color[i] = WHITE;
_dep[i] = -1;
_prt[i] = -1;
_vist[i] = -1;
}
color[s] = GRAY;
_dep[s] = 0;
_prt[s] = -1;
_vist[time] = s;
lnkgphnd<edge> *p = _nd[s];
while(p)
{
if (color[p->_n] == WHITE)
{
color[p->_n] = GRAY;
DFSrecur(p->_n , color , ++time , s);
}
p = p->next;
}
color[s] = BLACK;
delete color;
return true;
}
template <class vertex , class edge>
void lnkgraph<vertex , edge>::DFSrecur(int s , int *color , int time , int pare)
{
color[s] = GRAY;
_dep[s] = time;
_prt[s] = pare;
_vist[time] = s;
lnkgphnd<edge> *p = _nd[s];
while(p)
{
if ( color[p->_n] == WHITE)
{
color[p->_n] = GRAY;
DFSrecur(p->_n , color , time+1 , s);
}
p = p->next;
}
color[s] = BLACK;
}
template <class vertex , class edge>
bool lnkgraph<vertex , edge>::DFS_stack(int s)
{
if (s > _vcnt)return false;
int time = 0 , i;
int *color = new int[_vcnt];
for (i = 0 ; i < _vcnt ; i++)
{
color[i] = WHITE;
_dep[i] = -1;
_prt[i] = -1;
_prt[i] = -1;
}
color[s] = GRAY;
_prt[s] = -1;
_dep[s] = 0;
_vist[time++] = s;
stack<int> _stack(_vcnt);
_stack.push(s);
while(_stack.height() != 0)
{
int nd;
_stack.top(nd);
lnkgphnd<edge> *p = _nd[nd];
while(p)
{
if (color[p->_n] == WHITE)
{
_stack.push(p->_n);
color[p->_n] = GRAY;
_prt[p->_n] = nd;
_dep[p->_n] = time;
_vist[time++] = p->_n;
break;
}
p = p->next;
}
if (p == NULL)
{
int nd;
_stack.pop(nd);
color[nd] = BLACK;
}
}
return true;
}
template <class vertex , class edge>
bool lnkgraph<vertex , edge>::visit_result()
{
if (_vcnt <= 0)return false;
cout<<"visit result is:";
for (int i = 0 ; i < _vcnt ; i++)
{
if (_vist[i] != -1)cout<<_ver[_vist[i]]<<",";
}
return true;
}
template<class edge> struct package
{
int i1;
int i2;
bh_node<edge> *pnd;
};
template <class vertex , class edge>
lnkgraph<vertex , edge> *lnkgraph<vertex , edge>::Prim(int n)
{
lnkgraph<vertex , edge> *mst;
if (n >= _vcnt || n < 0)return NULL;
bh_node<edge> *bhnd;
bool *isInHeap = new bool[_vcnt];
package<edge> *pbag = new package<edge>[_vcnt];
mst = new lnkgraph<vertex , edge>(_vcnt);
bin_heap<edge> bh;
for (int i = 0 ; i < _vcnt ; i++)
{
bh_node<edge> *nd = new bh_node<edge>;
nd->sibling = nd->child = nd->parent = NULL;
nd->degree = 0;
nd->key = INT_MAX;
// bhdata[i*2] = i;
// bhdata[i*2+1] = -1;
pbag[i].i1 = i;
pbag[i].i2 = -1;
pbag[i].pnd = nd;
nd->data = &pbag[i];
bh.bin_heap_insert(nd);
isInHeap[i] = true;
}
bh.bin_heap_decrease_key(pbag[n].pnd,INT_MIN);
while(!bh.bin_heap_is_empty())
{
bhnd = bh.bin_heap_extract_min();
int i1 = ((package<edge>*)(bhnd->data))->i1;
int i2 = ((package<edge>*)(bhnd->data))->i2;
mst->insert_vertex(_ver[i1]);
if (i2 != -1)
{
mst->insert_edge(i1,i2,bhnd->key);
mst->insert_edge(i2,i1,bhnd->key);
}
isInHeap[i1] = false;
lnkgphnd<edge> *p = _nd[i1];
while(p)
{
if(isInHeap[p->_n] && p->_e < pbag[p->_n].pnd->key)
{
_prt[p->_n] = i1;
((int*)(pbag[p->_n].pnd->data))[1] = i1;
bh.bin_heap_decrease_key(pbag[p->_n].pnd , p->_e);
}
p = p->next;
}
}
return mst;
}
#endif
// graph.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "base.h"
int _tmain(int argc, _TCHAR* argv[])
{
lnkgraph<int , int> mtxg(9);
for (int i = 1 ; i <= 9 ; i++)
{
mtxg.insert_vertex(i);
}
mtxg.insert_edge(0,1,4);
mtxg.insert_edge(1,0,4);
mtxg.insert_edge(0,7,8);
mtxg.insert_edge(7,0,8);
mtxg.insert_edge(1,7,11);
mtxg.insert_edge(7,1,11);
mtxg.insert_edge(1,2,8);
mtxg.insert_edge(2,1,8);
mtxg.insert_edge(2,3,7);
mtxg.insert_edge(3,2,7);
mtxg.insert_edge(2,8,2);
mtxg.insert_edge(8,2,2);
mtxg.insert_edge(2,5,4);
mtxg.insert_edge(5,2,4);
mtxg.insert_edge(3,4,9);
mtxg.insert_edge(4,3,9);
mtxg.insert_edge(3,5,14);
mtxg.insert_edge(5,3,14);
mtxg.insert_edge(4,5,10);
mtxg.insert_edge(5,4,10);
mtxg.insert_edge(5,6,2);
mtxg.insert_edge(6,5,2);
mtxg.insert_edge(6,7,1);
mtxg.insert_edge(7,6,1);
mtxg.insert_edge(6,8,6);
mtxg.insert_edge(8,6,6);
mtxg.insert_edge(7,8,7);
mtxg.insert_edge(8,7,7);
lnkgraph<int , int> *mst = mtxg.Prim(0);
return 0;
}