/* Graph Sort * Copyleft (C) 2002 David Griffiths * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "GraphSort.h" //#define GRAPHSORT_TRACE ////////////////////////////////////////////////////////// GraphSort::GraphSort() { } GraphSort::~GraphSort() { } void GraphSort::Clear() { //m_Sorted.clear(); m_Graph.clear(); } const list &GraphSort::GetSortedList() { return m_Sorted; } void GraphSort::Sort() { // walk back from all the roots m_Sorted.clear(); list RootNodes; bool FoundRoot=false; for (map::iterator i=m_Graph.begin(); i!=m_Graph.end(); i++) { // if there are no outputs, this must be a root if (i->second.Outputs.empty()) { FoundRoot=true; RecursiveWalk(i->first); } } // no roots found - try looking for a terminal node and recursing from // there, this makes circular graphs work. if (!FoundRoot) { for (map::iterator i=m_Graph.begin(); i!=m_Graph.end(); i++) { // if there are no outputs, this must be a root if (i->second.IsTerminal) { RecursiveWalk(i->first); } } } #ifdef GRAPHSORT_TRACE for(list::iterator i=m_Sorted.begin(); i!=m_Sorted.end(); i++) { cerr<<*i<<" "; } cerr<::iterator i=m_Graph.find(node); for(list::iterator ii=i->second.Inputs.begin(); ii!=i->second.Inputs.end(); ii++) { RecursiveWalk(*ii); } } void GraphSort::Dump() { for (map::iterator i=m_Graph.begin(); i!=m_Graph.end(); i++) { cerr<<"Node "<first<::iterator si=m_Graph.find(SID); if (si==m_Graph.end()) { Node newnode; newnode.IsTerminal = STerminal; m_Graph[SID]=newnode; #ifdef GRAPHSORT_TRACE cerr<<"added "<::iterator di=m_Graph.find(DID); if (di==m_Graph.end()) { Node newnode; newnode.IsTerminal = DTerminal; m_Graph[DID]=newnode; #ifdef GRAPHSORT_TRACE cerr<<"added "<::iterator si=m_Graph.find(SID); if (si==m_Graph.end()) { cerr<<"GraphSort::RemoveConnection - can't find source node"<::iterator di=m_Graph.find(DID); if (di==m_Graph.end()) { cerr<<"GraphSort::RemoveConnection - can't find dest node"<::iterator soi = find(si->second.Outputs.begin(), si->second.Outputs.end(), DID); if (soi==si->second.Outputs.end()) cerr<<"GraphSort::RemoveConnection - can't find soi"<second.Outputs.erase(soi); list::iterator dii = find(di->second.Inputs.begin(), di->second.Inputs.end(), SID); if (dii==di->second.Inputs.end()) cerr<<"GraphSort::RemoveConnection - can't find dii"<second.Inputs.erase(dii); // check to remove the nodes if (si->second.Outputs.empty() && si->second.Inputs.empty()) { m_Graph.erase(si); #ifdef GRAPHSORT_TRACE cerr<<"removed "<second.Outputs.empty() && di->second.Inputs.empty()) { m_Graph.erase(di); #ifdef GRAPHSORT_TRACE cerr<<"removed "<