Вот механический способ сделать рекурсивный алгоритм нерекурсивным.
bool Search(BstNode* root, string data) {
if (root == NULL) return false;
else if (root->data == data) return true;
else if (data <= root->data) return Search(root->left, data);
else return Search(root->right, data);
}
Объедините состояние (аргументы и локальные переменные):
bool Search(BstNode* root, string data) {
struct State {
BstNode* root;
string data;
};
State state{root, data};
if (state.root == NULL) return false;
else if (state.root->data == state.data) return true;
else if (data <= state.root->data) return Search(state.root->left, state.data);
else return Search(state.root->right, state.data);
}
завернуть тело в цикл:
bool Search(BstNode* root, string data) {
struct State {
BstNode* root;
string data;
};
State state{root, data};
while(true) {
if (state.root == NULL) return false;
else if (state.root->data == state.data) return true;
else if (data <= state.root->data) return Search(state.root->left, data);
else return Search(state.root->right, data);
}
}
Замените случай, когда вы завершаете рекурсию (возвращаете recursive_call) с изменением состояния и продолжаете:
bool Search(BstNode* root, string data) {
struct State {
BstNode* root;
string data;
};
State state{root, data};
while(true) {
if (state.root == NULL) return false;
else if (state.root->data == state.data) return true;
else if (data <= state.root->data) {
state = {state.root->left, state.data};
continue;
} else {
state = {state.root->right, state.data};
continue;
}
}
}
Теперь, если есть еще какие-либо рекурсивные вызовы, которые не являются return recursive_call
, добавьте ручной стек состояния и нажмите/вытолкните его вместо изменения обратно. Включите расположение состояния возврата в виде void**
в код с метками.
Здесь это не требуется, поэтому я не буду этого делать.
person
Yakk - Adam Nevraumont
schedule
11.10.2016
root->left
илиroot->right
перед следующей итерацией. - person BoBTFish   schedule 11.10.2016