组合数学实验——求欧拉迹算法

还是以前写的......

算法:组合数学中文第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");
};

你可能感兴趣的:(图,组合数学,欧拉回路)