还是以前写的......
算法:组合数学中文第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"); };