- 为了方便,把写好的邻接表ADT放在这里,以备不时之需
- 给学弟学妹们参考
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
template<class TypeOfEdge>
struct edgeNode{
int data;
TypeOfEdge weight;
edgeNode<TypeOfEdge> *next;
edgeNode(const int &d, edgeNode<TypeOfEdge> *ptr = NULL) {
next = ptr;
data = d;
}
edgeNode(const int &d, const TypeOfEdge &w, edgeNode<TypeOfEdge> *ptr = NULL){
next = ptr;
data = d;
weight = w;
}
edgeNode(){
}
int getData(){
return data;}
TypeOfEdge getWeight(){
return weight;}
void SetLink( edgeNode<TypeOfEdge> *link ){
next = link; }
void SetData( int value ){
data = value; }
void SetWeight(TypeOfEdge value ){
weight = value; }
};
template<class TypeOfVer, class TypeOfEdge>
struct verNode{
TypeOfVer ver;
edgeNode<TypeOfEdge> *head;
verNode(edgeNode<TypeOfEdge> *h = NULL){
head = h;}
TypeOfVer getVer(){
return ver;}
edgeNode<TypeOfEdge> getHead(){
return head;}
void setVer(TypeOfVer value){
ver = value;}
void setHead(edgeNode<TypeOfEdge> value){
head = value;}
};
template <class TypeOfVer, class TypeOfEdge>
class adjlist_graph{
private:
int Vers;
int Edges;
verNode<TypeOfVer,TypeOfEdge> *verList;
string GraphKind;
bool Delete_Edge( int u, int v );
bool DFS(int u, int &num, int visited[]);
bool CheckRoute(int u, int v, int visited[]);
public:
adjlist_graph( const string &kd, int vSize, const TypeOfVer d[]);
adjlist_graph( const string &kd, int vSize, int eSize, const TypeOfVer d[], int **e);
adjlist_graph( const string &kd, int vSize, int eSize, const TypeOfVer d[], int **e, const TypeOfEdge w[]);
bool GraphisEmpty() {
return Vers == 0; }
string GetGraphKind(){
return GraphKind; }
bool GetVer(int u, TypeOfVer &data);
int GetFirstAdjVex(int u, int &v);
int GetNextAdjVex(int u, int v, int &w);
bool PutVer(int u, TypeOfVer data);
bool InsertVer(const TypeOfVer &data);
int LocateVer(TypeOfVer data);
bool ExistEdge(int u, int v);
bool PrintVer();
bool PrintAdjList();
bool GetWeight(int u,int v,int &w);
int Get_Degree(int u);
int Get_InDegree(int u);
bool CheckRoute(int u, int v);
bool TopSort();
bool U_Judge_Cir();
bool isDAG();
bool TopSort(int &num, int topsort[]);
int GetVerNum(){
return Vers;}
int GetEdgeNum(){
return Edges;}
bool Insert_Edge(int u, int v);
bool Insert_Edge(int u, int v, TypeOfEdge w);
bool DeleteVer(const int u);
bool DeleteEdge( int u, int v );
void DFS_Traverse(int u);
void BFS_Traverse(int u);
~adjlist_graph();
bool Get_CriticalPath(int ve[], int vl[],int topSort[]);
};
template<class TypeOfVer,class TypeOfEdge>
adjlist_graph<TypeOfVer,TypeOfEdge>::adjlist_graph(const string &kd, int vSize, const TypeOfVer d[]){
GraphKind = kd;
Vers = vSize;
Edges = 0;
verList = new verNode<TypeOfVer,TypeOfEdge>[vSize];
for(int i=0;i<vSize;i++) verList[i].ver = d[i];
}
template<class TypeOfVer,class TypeOfEdge>
adjlist_graph<TypeOfVer,TypeOfEdge>::adjlist_graph(const string&kd, int vSize, int eSize, const TypeOfVer d[], int** e){
GraphKind = kd;
Vers = vSize;
Edges = eSize;
verList = new verNode<TypeOfVer,TypeOfEdge>[vSize];
if(GraphKind == "UDG"||GraphKind == "DG"){
for(int i=0; i<vSize; i++) verList[i].ver = d[i];
for(int i=0; i<eSize; i++){
int u = e[i][0];
int v = e[i][1];
verList[u].head = new edgeNode<TypeOfEdge>(v,verList[u].head);
if(GraphKind == "UDG") verList[v].head = new edgeNode<TypeOfEdge>(u,verList[v].head);
}
}
}
template<class TypeOfVer,class TypeOfEdge>
adjlist_graph<TypeOfVer,TypeOfEdge>::adjlist_graph(const string &kd, int vSize, int eSize, const TypeOfVer d[], int **e, const TypeOfEdge w[]){
GraphKind = kd;
Vers = vSize;
Edges = eSize;
verList = new verNode<TypeOfVer,TypeOfEdge>[vSize];
if(GraphKind == "UDN"||GraphKind == "DN"){
for(int i=0; i<vSize; i++){
verList[i].ver = d[i];
}for(int i=0; i<eSize; i++){
int u = e[i][0];
int v = e[i][1];
verList[u].head = new edgeNode<TypeOfEdge>(v,w[i],verList[u].head);
if(GraphKind == "UDN") verList[v].head = new edgeNode<TypeOfEdge>(u,w[i],verList[v].head);
}
}
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::InsertVer(const TypeOfVer &data){
verNode<TypeOfVer,TypeOfEdge>* new_verlist =new verNode<TypeOfVer, TypeOfEdge>[Vers+1];
for(int i=0;i<Vers;i++){
new_verlist[i].ver = verList[i].ver;
new_verlist[i].head = verList[i].head;
}
new_verlist[Vers].ver = data;
new_verlist[Vers].head = NULL;
delete[] verList;
Vers++;
verList = new_verlist;
return true;
}
template<class TypeOfVer,class TypeOfEdge>
int adjlist_graph<TypeOfVer,TypeOfEdge>::LocateVer(TypeOfVer data){
for(int i=0; i<Vers; i++){
if(data == verList[i].ver) return i;
}
return -1;
}
template<class TypeOfVer, class TypeOfEdge>
bool adjlist_graph<TypeOfVer, TypeOfEdge>::ExistEdge(int u, int v){
if(u<0||v<0||u>=Vers||v>=Vers) return false;
if(u == v) return false;
edgeNode<TypeOfEdge> *p;
p = verList[u].head;
if(!p) return false;
while(p&&p->data!=v) p=p->next;
if(p == NULL) return false;
return true;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::Delete_Edge(int u, int v){
if(u<0||v<0||u>=Vers||v>=Vers) return false;
if(!ExistEdge(u,v)) return false;
edgeNode<TypeOfEdge> *p,*q;
p = verList[u].head;
if(p->data == v){
verList[u].head = p->next;
delete p;
Edges--;
return true;
}
while(p->next&&p->next->data!=v) p=p->next;
q = p->next;
p->next = q->next;
delete q;
Edges--;
return true;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::DeleteEdge(int u,int v){
if(GraphKind == "DG"||GraphKind == "DN"){
if(Delete_Edge(u,v)) return true;
return false;
}
if(GraphKind == "UDG"||GraphKind == "UDN"){
if(Delete_Edge(u,v)&&Delete_Edge(v,u)){
Edges++;
return true;
}
return false;
}
return false;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::DeleteVer(const int u){
edgeNode<TypeOfEdge> *p,*q;
if(u<0||u>=Vers) return false;
p=verList[u].head;
for(int i=0;i<Vers;i++){
if(i!=u) {
DeleteEdge(i,u);
p = verList[i].head;
while(p){
if(p->data > u) p->data--;
p=p->next;
}
}else{
if(GraphKind == "DG"||GraphKind == "DN"){
p = verList[i].head;
while(p){
q = p->next;
Edges--;
delete p;
p = q;
}
}
}
}
for(int j=u+1;j<Vers;j++) verList[j-1] = verList[j];
Vers--;
return true;
}
template<class TypeOfVer,class TypeOfEdge>
void adjlist_graph<TypeOfVer,TypeOfEdge>::DFS_Traverse(int u){
int *vis = new int[Vers];
for(int i=0;i<Vers;i++) vis[i] = 0;
DFS(u,u,vis);
}
int f = 1;
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::DFS(int u, int &num, int *visited){
edgeNode<TypeOfEdge> *p;
p = verList[u].head;
if(!visited[u]) {
if(f == 0) cout<<"->";f = 0;
cout<<verList[u].ver;
visited[u] = 1;
while(p){
DFS(p->data,num,visited);
p=p->next;
}
}
}
template<class TypeOfVer,class TypeOfEdge>
void adjlist_graph<TypeOfVer,TypeOfEdge>::BFS_Traverse(int u){
int *vis = new int[Vers];
for(int i=0;i<Vers;i++) vis[i] = 0;
queue<int> q;
edgeNode<TypeOfEdge> *p;
q.push(u);
while(!q.empty()){
int v = q.front();
if(!vis[v]){
p = verList[v].head;
while(p){
q.push(p->data);
p=p->next;
}if(f==0) cout<<"->";f = 0;
cout<<verList[v].ver;
}
vis[v] = 1;
q.pop();
}
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::CheckRoute(int u,int v){
int *vis = new int[Vers];
for(int i=0;i<Vers;i++) vis[i] = 0;
CheckRoute(u,v,vis);
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::CheckRoute(int u,int vv,int vis[]){
queue<int> q;
edgeNode<TypeOfEdge> *p;
q.push(u);
while(!q.empty()){
int v = q.front();
if(!vis[v]){
p = verList[v].head;
while(p){
q.push(p->data);
p=p->next;
}
}
vis[v] = 1;
if(v == vv) return true;
q.pop();
}
return false;
}
template<class TypeOfVer, class TypeOfEdge>
bool adjlist_graph<TypeOfVer, TypeOfEdge>::GetWeight(int u, int v, int &w){
edgeNode<TypeOfEdge> *p;
if(u<0||v<0||u>Vers||v>Vers) return false;
p = verList[u].head;
while(p){
if(p->data == v){
w = p->weight;
return true;
}
p=p->next;
}p = verList[v].head;
while(p){
if(p->data == u){
w = p->weight;
return true;
}
p=p->next;
}
return false;
}
template<class TypeOfVer,class TypeOfEdge>
int adjlist_graph<TypeOfVer,TypeOfEdge>::Get_Degree(int u){
int ans = 0;
edgeNode<TypeOfEdge> *p;
p = verList[u].head;
while(p){
ans++;
p=p->next;
}
if(ans!=0) return ans;
return -1;
}
template<class TypeOfVer,class TypeOfEdge>
int adjlist_graph<TypeOfVer, TypeOfEdge>::Get_InDegree(int u){
if(GraphKind == "UDG"||GraphKind == "UDN") return -1;
int ans = 0;
edgeNode<TypeOfEdge> *p;
for(int i=0;i<Vers;i++){
if(i!=u){
p = verList[i].head;
while(p){
if(p->data == u) ans++;
p=p->next;
}
}
}
if(ans!=0) return ans;
return -1;
}
template<class TypeOfVer,class TypeOfEdge>
int adjlist_graph<TypeOfVer,TypeOfEdge>::GetFirstAdjVex(int u, int &v){
edgeNode<TypeOfEdge> *q;
q = verList[u].head;
while(q){
return q->data;
}
return -1;
}
template<class TypeOfVer,class TypeOfEdge>
int adjlist_graph<TypeOfVer,TypeOfEdge>::GetNextAdjVex(int u, int v, int &w){
edgeNode<TypeOfEdge> *q;
q = verList[u].head;
while(q){
if(q->data == v){
if(!q->next) return -1;
return q->next->data;
}q=q->next;
}
return -1;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::Insert_Edge(int u, int v){
if(ExistEdge(u,v)) return false;
edgeNode<TypeOfEdge> *q,*p,*r;
q = verList[u].head;
Edges++;
if(!q){
q = new edgeNode<TypeOfEdge>;
q->data = v;
q->next = NULL;
}else{
p = q;
r = new edgeNode<TypeOfEdge>;
r->data = v;
q = r;
q->next = p;
}verList[u].head = q;
return true;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::Insert_Edge(int u, int v, TypeOfEdge w){
if(u<0||v<0||u>=Vers||v>=Vers) return false;
if(ExistEdge(u,v)) return false;
if(GraphKind == "UDN"){
verList[u].head = new edgeNode<TypeOfEdge>(v,w,verList[u].head);
verList[v].head = new edgeNode<TypeOfEdge>(u,w,verList[v].head);
Edges++;
}if(GraphKind == "DN"){
verList[u].head = new edgeNode<TypeOfEdge>(v,w,verList[u].head);
Edges++;
}
return true;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::PrintVer(){
if(Vers == 0) return false;
for(int i=0;i<Vers;i++){
if(i) cout<<" ";
cout<<verList[i].ver;
}
cout<<endl;
return true;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::PrintAdjList(){
if(Vers == 0) return false;
edgeNode<TypeOfEdge> *p;
for(int i=0;i<Vers;i++){
p = verList[i].head;
cout<<verList[i].ver;
if(p) cout<<"->";
while(p){
if(GraphKind == "DG"||GraphKind == "UDG") cout<<p->data;
else cout<<p->data<<'('<<p->weight<<')';
p=p->next;
if(p) cout<<"->";
}
cout<<endl;
}
}
template<class TypeOfVer,class TypeOfEdge>
adjlist_graph<TypeOfVer,TypeOfEdge>::~adjlist_graph(){
edgeNode<TypeOfEdge> *p;
for(int i=0;i<Vers;i++){
if((p = verList[i].head)){
verList[i].head = p->next;
delete p;
}
}
delete [] verList;
}