还是以前写的......
算法:组合数学中文第4版 机械工业出版社 P299
同样隐藏掉ID
//
// //
// Project Name: Eulerian_Trace //
// //
// File Name: EGraph.h //
// //
// Author: Victor Zhang //
// //
// ID: 21*****92 //
// //
// Create Date: May 17. 2009 //
// //
//
struct ET_Node
{
int point_one;
int point_two;
int route_num;
ET_Node* right;
ET_Node* down;
};
struct ET_Node_Head
{
int ID;
ET_Node_Head* next;
ET_Node* right;
ET_Node* down;
};
struct Link_Unit
{
Link_Unit* next;
int value;
};
class ETGraph
{
private:
ET_Node_Head* head;
Link_Unit* main_Link_Head;
private:
ET_Node_Head* GetNodeHead(int);
ET_Node* GetNode(int, int);
int GetRoute(ET_Node*);
int GetRoute(int, int);
bool DelRoute(ET_Node*);
bool AddNodeHead(int);
public:
ETGraph()
{
head = NULL;
main_Link_Head = NULL;
};
bool AddNode(int, int, int);
bool SetRoute(int, int, int);
Link_Unit* Find_Circle();
bool Compose(Link_Unit*);
void Find_ET();
bool DelNode(int, int);
bool DelRoute(int, int);
void DelAllNodes();
void DelLinks();
bool ReadFromFile();
void PrintToFile();
~ETGraph()
{
DelAllNodes();
DelLinks();
};
};
//
// //
// Project Name: Eulerian_Trace //
// //
// File Name: EGraph.cpp //
// //
// Author: Victor Zhang //
// //
// ID: 21*****92 //
// //
// Create Date: May 17. 2009 //
// //
//
#include <iostream>
#include <fstream>
#include <iomanip>
#include "ETGraph.h"
using namespace std;
ET_Node_Head* ETGraph::GetNodeHead(int ID)
{
if (!(this->head)) return NULL;
else
{
ET_Node_Head* p = NULL;
p = this->head;
while (p && (p->ID != ID))
p = p->next;
return p;
};
};
ET_Node* ETGraph::GetNode(int i, int j)
{
ET_Node_Head* p = this->GetNodeHead(i);
if (!p) return NULL;
ET_Node* pp = p->down;
while (pp && (pp->point_two != j)) pp = pp->down;
if (!pp) return NULL;
return (pp->point_one == i) ? pp : NULL;
};
int ETGraph::GetRoute(ET_Node* p)
{
if (!p) return 0;
return p->route_num;
};
int ETGraph::GetRoute(int i, int j)
{
return this->GetRoute(this->GetNode(i, j));
};
bool ETGraph::DelRoute(ET_Node* p)
{
if (!p) return false;
if (p->route_num <= 0) return false;
p->route_num--;
if (p->route_num == 0) this->DelNode(p->point_one, p->point_two);
return true;
};
bool ETGraph::AddNodeHead(int ID)
{
ET_Node_Head* p = new ET_Node_Head;
if (!p) return false;
p->next = NULL;
if (!(this->head)) this->head = p;
else
{
ET_Node_Head* p1;
ET_Node_Head* p2;
p1 = this->head;
p2 = this->head;
p2 = p1->next;
while (p1 && p2 && (p2->ID < ID))
{
p1 = p2;
p2 = p2->next;
};
if (!p2)
{
p1->next = p;
p->next = NULL;
}
else if (p2->ID == ID)
{
delete p;
return false;
}
else
{
p1->next = p;
p->next = p2;
};
};
p->ID = ID;
p->down = p->right = NULL;
return true;
};
bool ETGraph::AddNode(int i, int j, int r)
{
if (this->GetNode(i, j)) return false;
ET_Node* p = new ET_Node;
ET_Node_Head* ph1 = this->GetNodeHead(i);
ET_Node_Head* ph2 = this->GetNodeHead(j);
if (!ph1)
{
this->AddNodeHead(i);
ph1 = this->GetNodeHead(i);
}
if (!ph2)
{
this->AddNodeHead(j);
ph2 = this->GetNodeHead(j);
};
if ((!ph1) || (!ph2))
{
delete p;
delete ph1;
delete ph2;
return false;
};
p->point_one = i;
p->point_two = j;
p->route_num = r;
ET_Node* p1;
ET_Node* p2;
p1 = p2 = ph1->down;
if (p1) p2 = p1->down;
while (p1 && p2 && (p2->point_two < j))
{
p1 = p2;
p2 = p2->down;
};
if (!p1)
{
ph1->down = p;
p->down = NULL;
}
else if (p1->point_two >= j)
{
ph1->down = p;
p->down = p1;
}
else if (p2 && (p2->point_two == j))
{
delete p;
return false;
}
else
{
p1->down = p;
p->down = p2;
};
p1 = p2 = ph2->right;
if (p1) p2 = p1->right;
while (p1 && p2 && (p2->point_one > i))
{
p1 = p2;
p2 = p2->right;
};
if (!p1)
{
ph2->right = p;
p->right = NULL;
}
else if (p1->point_one <= i)
{
ph2->right = p;
p->right = p1;
}
else if (p2 && (p2->point_one == i))
{
delete p;
return false;
}
else
{
p1->right = p;
p->right = p2;
};
return true;
};
bool ETGraph::SetRoute(int i, int j, int r)
{
ET_Node* p;
p = this->GetNode(i, j);
if (!p) return false;
p->route_num = r;
return true;
};
Link_Unit* ETGraph::Find_Circle()
{
if (!(this->main_Link_Head))
{
Link_Unit* p;
Link_Unit* pp;
ET_Node* pNd;
if (!(this->head)) return NULL;
pNd = this->head->down;
p = new Link_Unit;
if (!p) return NULL;
p->value = this->head->ID;
p->next = NULL;
pp = this->main_Link_Head = p;
ET_Node_Head* ph = this->GetNodeHead(pNd->point_two);
this->DelRoute(pNd->point_one, pNd->point_two);
while (ph && ph != this->head)
{
pNd = ph->right;
if (pNd)
{
p = new Link_Unit;
if (!p) return NULL;
p->value = pNd->point_two;
pp->next = p;
p->next = NULL;
pp = p;
ph = this->GetNodeHead(pNd->point_one);
this->DelRoute(pNd->point_one, pNd->point_two);
continue;
};
pNd = ph->down;
if (pNd)
{
p = new Link_Unit;
if (!p) return NULL;
p->value = ph->ID;
pp->next = p;
p->next = NULL;
pp = p;
ph = this->GetNodeHead(pNd->point_two);
this->DelRoute(pNd->point_one, pNd->point_two);
continue;
};
return NULL;
};
if (ph == this->head)
{
p = new Link_Unit;
if (!p) return NULL;
p->value = ph->ID;
pp->next = p;
p->next = NULL;
return this->main_Link_Head;
};
return NULL;
}
else
{
Link_Unit* p;
Link_Unit* pp;
Link_Unit* pLh;
ET_Node* pNd;
ET_Node_Head* ph;
ET_Node_Head* pHh;
p = this->main_Link_Head;
while (p)
{
ph = this->GetNodeHead(p->value);
pNd = ph->right;
if (pNd)
{
pHh = ph;
ph = this->GetNodeHead(pNd->point_one);
break;
};
pNd = ph->down;
if (pNd)
{
pHh = ph;
ph = this->GetNodeHead(pNd->point_two);
break;
};
p = p->next;
};
if (!pNd) return NULL;
p = new Link_Unit;
if (!p) return NULL;
pLh = p;
p->value = pHh->ID;
p->next = NULL;
pp = pLh;
this->DelRoute(pNd->point_one, pNd->point_two);
while (ph && ph != pHh)
{
pNd = ph->right;
if (pNd)
{
p = new Link_Unit;
if (!p) return NULL;
p->value = pNd->point_two;
pp->next = p;
p->next = NULL;
pp = p;
ph = this->GetNodeHead(pNd->point_one);
this->DelRoute(pNd->point_one, pNd->point_two);
continue;
};
pNd = ph->down;
if (pNd)
{
p = new Link_Unit;
if (!p) return NULL;
p->value = pNd->point_one;
pp->next = p;
p->next = NULL;
pp = p;
ph = this->GetNodeHead(pNd->point_two);
this->DelRoute(pNd->point_one, pNd->point_two);
continue;
};
return NULL;
};
if (ph == this->head)
{
p = new Link_Unit;
if (!p) return NULL;
p->value = ph->ID;
pp->next = p;
p->next = NULL;
return pLh;
};
return NULL;
};
};
bool ETGraph::Compose(Link_Unit* p)
{
if (!p) return false;
if (!(this->main_Link_Head))
{
this->main_Link_Head = p;
return true;
}
else if (p == this->main_Link_Head)
return true;
else
{
Link_Unit* ph;
ph = this->main_Link_Head;
while (ph && (ph->value != p->value)) ph = ph->next;
if (!ph) return false;
Link_Unit* pn;
pn = ph->next;
Link_Unit* pd = p;
p = p->next;
delete pd;
ph->next = p;
while (p->next) p = p->next;
p->next = pn;
return true;
};
};
void ETGraph::Find_ET()
{
Link_Unit* p;
p = this->Find_Circle();
while (p)
{
this->Compose(p);
p = this->Find_Circle();
};
return;
};
bool ETGraph::DelNode(int i, int j)
{
ET_Node* p = this->GetNode(i, j);
if (!p) return false;
ET_Node_Head* ph = this->GetNodeHead(i);
if (!ph) return false;
ET_Node* pp = ph->down;
ET_Node* pn = p->down;
if (pp == p)
{
ph->down = pn;
}
else
{
while (pp && pp->down != p) pp = pp->down;
if (!pp) return false;
pp->down = pn;
};
ph = this->GetNodeHead(j);
if (!ph) return false;
pp = ph->right;
pn = p->right;
if (pp == p)
{
ph->right = pn;
}
else
{
while (pp && pp->right != p) pp = pp->right;
if (!pp) return false;
pp->right = pn;
};
delete p;
return true;
};
bool ETGraph::DelRoute(int i, int j)
{
return this->DelRoute(this->GetNode(i, j));
};
void ETGraph::DelAllNodes()
{
ET_Node_Head* h = this->head;
ET_Node* p;
ET_Node* pn;
while (h)
{
p = h->down;
while (p)
{
pn = p->down;
delete p;
p = pn;
};
this->head = h->next;
delete h;
h = this->head;
};
};
void ETGraph::DelLinks()
{
Link_Unit* p;
while (this->main_Link_Head)
{
p = this->main_Link_Head->next;
delete this->main_Link_Head;
this->main_Link_Head = p;
};
};
bool ETGraph::ReadFromFile()
{
ifstream inputFile ("Graph_data.txt", ios::in);
if (!inputFile)
{
cout<<"Error in reading file :\"Graph_data.txt\"."<<endl;
system("pause");
return false;
};
try
{
int f = 9;
int i;
int j;
int r;
i = j = r = 0;
inputFile>>i>>j>>r;
if (!(this->AddNode(i, j, r))) return false;
while(inputFile>>i>>j>>r)
if (!(this->AddNode(i, j, r)))
return false;
}
catch(...)
{
cout<<"Error in reading file :\"Graph_data.txt\"."<<endl;
system("pause");
inputFile.close();
this->DelAllNodes();
return false;
};
inputFile.close();
return true;
};
void ETGraph::PrintToFile()
{
ofstream outputFile ("Graph_output.txt", ios::out);
Link_Unit* p;
p = this->main_Link_Head;
while (p)
{
cout<<p->value<<" ";
outputFile<<p->value<<" ";
p = p->next;
};
};
//
// //
// Project Name: Eulerian_Trace //
// //
// File Name: main.cpp //
// //
// Author: Victor Zhang //
// //
// ID: 21*****92 //
// //
// Create Date: May 17. 2009 //
// //
//
#include <iostream>
using namespace std;
#include "ETGraph.h"
void main()
{
ETGraph a;
a.ReadFromFile();
a.Find_ET();
a.PrintToFile();
system("pause");
};