[英]How to transform a recursive function to an iterative one
我正在嘗試使用堆棧將此遞歸 function 轉換為迭代:
void GetToTownRecursive(int x, Country &country, AList *accessiblesGroup, vector<eTownColor> &cities_colors)
{
cities_colors[x - 1] = eTownColor::BLACK;
accessiblesGroup->Insert(x);
List *connected_cities = country.GetConnectedCities(x);
if (!connected_cities->IsEmpty())
{
ListNode *curr_city = connected_cities->First();
while (curr_city != nullptr)
{
if (cities_colors[curr_city->GetTown() - 1] == eTownColor::WHITE)
{
GetToTownRecursive(curr_city->GetTown(), country, accessiblesGroup, cities_colors);
}
curr_city = curr_city->GetNextNode();
}
}
}
function 將城鎮編號作為輸入並返回與該城鎮相連(直接和間接)的城鎮列表。
由於內部的 while 循環以及遞歸調用后采取的唯一操作是提升列表迭代器 - curr_city
,我很難轉換它。 在這種情況下我應該將什么壓入堆棧?
很高興為您提供幫助!
遞歸調用之后采取的操作是 while 循環的全部剩余部分(所有剩余的迭代)。 在堆棧上,您必須保存在遞歸調用期間可能更改但之后需要的所有變量。 在這種情況下,這只是curr_city
的值。
如果goto
仍然存在,則可以將遞歸調用替換為:
curr_city
x = curr_city->GetTown()
那么最后,你必須
curr_city
,恢復它並在 (3) 之后轉到因為對這種事情使用 gotos 是不可接受的(它們使您的代碼難以理解),所以您必須將 function 分成 3 個頂級部分:
通常,在此重新安排之后,您可以進行大量清理和簡化工作。
基本思想如下所示。
void GetToTown(int x, Country &country, AList *accessiblesGroup,
vector<eTownColor> &cities_colors)
{
Stack<int> pendingX = new ...
pendingX.push(x);
while (!pendingX.isEmpty()) {
int localX = pendingX.Pop();
cities_colors[localX - 1] = eTownColor::BLACK;
accessiblesGroup->Insert(localX);
List *connected_cities = country.GetConnectedCities(localX);
if (!connected_cities->IsEmpty())
{
ListNode *curr_city = connected_cities->First();
while (curr_city != nullptr)
{
if (cities_colors[curr_city->GetTown() - 1] == nColor::WHITE)
{
pendingX.Push(curr_city->GetTown());
}
curr_city = curr_city->GetNextNode();
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.