Add generate forest function

Now traverse can generate forest
This commit is contained in:
Linloir 2021-12-06 08:24:38 +08:00
parent fe61551f36
commit 234994c385
4 changed files with 138 additions and 57 deletions

View File

@ -230,7 +230,7 @@ void ALGraph::ResetDistance(){
}
}
void ALGraph::DFS(int strtID){
void ALGraph::DFS(int strtID, bool generateForest){
if(strtID == -1)
return;
vector<int> awaitVexList;
@ -254,9 +254,35 @@ void ALGraph::DFS(int strtID){
nextArc->visit();
vexList[nextVex].visit();
}
if(generateForest){
for(int i = 0; i < vexList.size(); i++){
if(vexList[i].visited) continue;
awaitVexList.clear();
awaitArcList.clear();
awaitVexList.push_back(i);
while(awaitVexList.size() > 0){
int nextVex = awaitVexList.back();
ALArc *nextArc = awaitArcList.size() > 0 ? awaitArcList.back() : nullptr;
awaitVexList.pop_back();
if(nextArc)
awaitArcList.pop_back();
for(ALArc *p = vexList[nextVex].firstArc; p != nullptr; p = p->nextArc){
if(vexList[p->eVexID].visited == false){
awaitVexList.push_back(p->eVexID);
awaitArcList.push_back(p);
if(type == UDG && GetIdOf(p->gArc->edVex()) != p->eVexID)
p->gArc->reverseDirection();
}
}
if(nextArc && !vexList[nextArc->eVexID].visited)
nextArc->visit();
vexList[nextVex].visit();
}
}
}
}
void ALGraph::BFS(int strtID){
void ALGraph::BFS(int strtID, bool generateForest){
if(strtID == -1)
return;
vector<int> awaitVexList;
@ -280,6 +306,32 @@ void ALGraph::BFS(int strtID){
nextArc->visit();
vexList[nextVex].visit();
}
if(generateForest){
for(int i = 0; i < vexList.size(); i++){
if(vexList[i].visited) continue;
awaitVexList.clear();
awaitArcList.clear();
awaitVexList.push_back(i);
while(awaitVexList.size() > 0){
int nextVex = awaitVexList[0];
ALArc *nextArc = awaitArcList.size() > 0 ? awaitArcList[0] : nullptr;
awaitVexList.erase(awaitVexList.begin());
if(nextArc)
awaitArcList.erase(awaitArcList.begin());
for(ALArc *p = vexList[nextVex].firstArc; p != nullptr; p = p->nextArc){
if(vexList[p->eVexID].visited == false){
awaitVexList.push_back(p->eVexID);
awaitArcList.push_back(p);
if(type == UDG && GetIdOf(p->gArc->edVex()) != p->eVexID)
p->gArc->reverseDirection();
}
}
if(nextArc && !vexList[nextArc->eVexID].visited)
nextArc->visit();
vexList[nextVex].visit();
}
}
}
}
void ALGraph::Dijkstra(int strtID){
@ -795,7 +847,7 @@ void AMLGraph::ResetDistance(){
}
}
void AMLGraph::DFS(int strtID){
void AMLGraph::DFS(int strtID, bool generateForest){
if(strtID == -1)
return;
vector<int> awaitVexList;
@ -820,9 +872,36 @@ void AMLGraph::DFS(int strtID){
nextArc->visit();
outVexList[nextVex].visit();
}
if(generateForest){
for(int i = 0; i < outVexList.size(); i++){
if(outVexList[i].visited) continue;
awaitVexList.clear();
awaitArcList.clear();
awaitVexList.push_back(i);
while(awaitVexList.size() > 0){
int nextVex = awaitVexList.back();
AMLArc *nextArc = awaitArcList.size() > 0 ? awaitArcList.back() : nullptr;
awaitVexList.pop_back();
if(nextArc)
awaitArcList.pop_back();
for(AMLArc *p = outVexList[nextVex].firstArc; p != nullptr; p = p->outVexID == strtID ? p->nextOutArc : p->nextInArc){
int endID = p->outVexID == nextVex ? p->inVexID : p->outVexID;
if(outVexList[endID].visited == false){
awaitVexList.push_back(endID);
awaitArcList.push_back(p);
if(type == UDG && GetIdOf(p->gArc->edVex()) != endID)
p->gArc->reverseDirection();
}
}
if(nextArc && !outVexList[nextVex].visited)
nextArc->visit();
outVexList[nextVex].visit();
}
}
}
}
void AMLGraph::BFS(int strtID){
void AMLGraph::BFS(int strtID, bool generateForest){
if(strtID == -1)
return;
vector<int> awaitVexList;
@ -847,6 +926,33 @@ void AMLGraph::BFS(int strtID){
nextArc->visit();
outVexList[nextVex].visit();
}
if(generateForest){
for(int i = 0; i < outVexList.size(); i++){
if(outVexList[i].visited) continue;
awaitVexList.clear();
awaitArcList.clear();
awaitVexList.push_back(i);
while(awaitVexList.size() > 0){
int nextVex = awaitVexList[0];
AMLArc *nextArc = awaitArcList.size() > 0 ? awaitArcList[0] : nullptr;
awaitVexList.erase(awaitVexList.begin());
if(nextArc)
awaitArcList.erase(awaitArcList.begin());
for(AMLArc *p = outVexList[nextVex].firstArc; p != nullptr; p = p->outVexID == strtID ? p->nextOutArc : p->nextInArc){
int endID = p->outVexID == nextVex ? p->inVexID : p->outVexID;
if(outVexList[endID].visited == false){
awaitVexList.push_back(endID);
awaitArcList.push_back(p);
if(type == UDG && GetIdOf(p->gArc->edVex()) != endID)
p->gArc->reverseDirection();
}
}
if(nextArc && !outVexList[nextVex].visited)
nextArc->visit();
outVexList[nextVex].visit();
}
}
}
}
void AMLGraph::Dijkstra(int strtID){

View File

@ -50,10 +50,10 @@ public:
/* Other Function */
virtual void ClearVisit() = 0;
virtual void ResetDistance() = 0;
virtual void DFS(int strtID) = 0;
virtual void DFS(MyGraphicsVexItem *strtVex) = 0;
virtual void BFS(int strtID) = 0;
virtual void BFS(MyGraphicsVexItem *strtVex) = 0;
virtual void DFS(int strtID, bool generateForest = false) = 0;
virtual void DFS(MyGraphicsVexItem *strtVex, bool generateForest = false) = 0;
virtual void BFS(int strtID, bool generateForest = false) = 0;
virtual void BFS(MyGraphicsVexItem *strtVex, bool generateForest = false) = 0;
virtual void Dijkstra(int strtID) = 0;
virtual void Dijkstra(MyGraphicsVexItem *strtVex) = 0;
@ -127,10 +127,10 @@ public:
/* Other Function */
void ClearVisit();
void ResetDistance();
void DFS(int strtID);
void DFS(MyGraphicsVexItem *strtVex){DFS(GetIdOf(strtVex));}
void BFS(int strtID);
void BFS(MyGraphicsVexItem *strtVex){BFS(GetIdOf(strtVex));}
void DFS(int strtID, bool generateForest = false);
void DFS(MyGraphicsVexItem *strtVex, bool generateForest = false){DFS(GetIdOf(strtVex), generateForest);}
void BFS(int strtID, bool generateForest = false);
void BFS(MyGraphicsVexItem *strtVex, bool generateForest = false){BFS(GetIdOf(strtVex), generateForest);}
void Dijkstra(int strtID);
void Dijkstra(MyGraphicsVexItem *strtVex){Dijkstra(GetIdOf(strtVex));}
AMLGraph* ConvertToAML();
@ -202,10 +202,10 @@ public:
/* Other Function */
void ClearVisit();
void ResetDistance();
void DFS(int strtID);
void DFS(MyGraphicsVexItem *strtVex){DFS(GetIdOf(strtVex));}
void BFS(int strtID);
void BFS(MyGraphicsVexItem *strtVex){BFS(GetIdOf(strtVex));}
void DFS(int strtID, bool generateForest = false);
void DFS(MyGraphicsVexItem *strtVex, bool generateForest = false){DFS(GetIdOf(strtVex), generateForest);}
void BFS(int strtID, bool generateForest = false);
void BFS(MyGraphicsVexItem *strtVex, bool generateForest = false){BFS(GetIdOf(strtVex), generateForest);}
void Dijkstra(int strtID);
void Dijkstra(MyGraphicsVexItem *strtVex){Dijkstra(GetIdOf(strtVex));}
ALGraph* ConvertToAL();

View File

@ -89,6 +89,14 @@ void MyCanvas::CreateSettings(int radius){
view->setType(id == 0 ? MyGraphicsView::DG : MyGraphicsView::UDG);
type = id == 0 ? DG : UDG;
});
singleSelectGroup *dfsSetting = new singleSelectGroup("Traverse Mode", this);
selectionItem *setGenerateTree = new selectionItem("Tree", "Generate tree", this);
selectionItem *setGenerateForest = new selectionItem("Forest", "Generate forest", this);
dfsSetting->AddItem(setGenerateTree);
dfsSetting->AddItem(setGenerateForest);
connect(dfsSetting, &singleSelectGroup::selectedItemChange, this, [=](int id){
generateForest = id == 1;
});
QWidget *whiteSpace = new QWidget(this);
whiteSpace->setFixedHeight(30);
horizontalValueAdjuster *aniSpeed = new horizontalValueAdjuster("Animation speed", 0.1, 20, 0.1, this);
@ -110,6 +118,7 @@ void MyCanvas::CreateSettings(int radius){
connect(delBtn, &textButton::clicked, this, [=](){emit setDel(this);});
settings->AddContent(delBtn);
settings->AddContent(saveBtn);
settings->AddContent(dfsSetting);
settings->AddContent(dirSetting);
settings->AddContent(structureSetting);
settings->AddContent(aniSpeed);
@ -353,19 +362,22 @@ void MyCanvas::Init(){
viewLog *newLog = new viewLog("[BFS] | --- BFS start ---");
newLog->setStyleSheet("color:#0078d4");
logDisplay->addWidget(newLog);
bfs();
g->BFS(view->selectedVex(), generateForest);
view->hasVisitedItem = true;
});
connect(startDfs, &textButton::clicked, this, [=](){
viewLog *newLog = new viewLog("[DFS] | --- DFS start ---");
newLog->setStyleSheet("color:#0078d4");
logDisplay->addWidget(newLog);
dfs();
g->DFS(view->selectedVex(), generateForest);
view->hasVisitedItem = true;
});
connect(startDij, &textButton::clicked, this, [=](){
viewLog *newLog = new viewLog("[Dij] | --- Dijkstra start ---");
newLog->setStyleSheet("color:#0078d4");
logDisplay->addWidget(newLog);
dijkstra();
g->Dijkstra(view->selectedVex());
view->hasVisitedItem = true;
if(g->GetInfoOf(view->selectedVex())->strtVexInfo == nullptr){
dijStart->setValue("Run dijkstra first");
dijPrev->setValue("Run dijkstra first");
@ -429,34 +441,3 @@ void MyCanvas::addVex(MyGraphicsVexItem *vex){
void MyCanvas::addArc(MyGraphicsLineItem *arc){
g->AddArc(arc);
}
void MyCanvas::dfs(){
MyGraphicsVexItem *strtVex = view->selectedVex();
if(strtVex != nullptr){
g->DFS(strtVex);
view->hasVisitedItem = true;
}
}
void MyCanvas::bfs(){
MyGraphicsVexItem *strtVex = view->selectedVex();
if(strtVex != nullptr){
g->BFS(strtVex);
view->hasVisitedItem = true;
}
}
void MyCanvas::dijkstra(){
MyGraphicsVexItem *strtVex = view->selectedVex();
if(strtVex){
g->Dijkstra(strtVex);
view->hasVisitedItem = true;
}
}
void MyCanvas::setWeight(int w){
MyGraphicsLineItem *arc = view->selectedArc();
if(arc){
g->SetWeight(arc, w);
}
}

View File

@ -25,6 +25,7 @@ private:
AbstractGraph *g;
int structure_type;
int type;
bool generateForest = false;
void CreateSettings(int r);
void Init();
@ -48,13 +49,6 @@ signals:
private slots:
void addVex(MyGraphicsVexItem*);
void addArc(MyGraphicsLineItem*);
//void delVex(MyGraphicsVexItem*);
//void delArc(MyGraphicsLineItem*);
void dfs();
void bfs();
void dijkstra();
void setWeight(int w);
void setAniRate(int step){view->setAniRate(step / 100.0);}
};