Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.06.2011, 09:41   #1
Kukurudza
Форумчанин
 
Регистрация: 02.06.2011
Сообщений: 282
По умолчанию рекурсивные функции

такой вопрос.
проверяю рекурсивно все узлы бинарного дерева на наличие некоторого элемента, чтобы потом его изменить по ссылке. если этот элемент обнаружен как выйти из рекурсии сразу же после это, не просматривая все остальные узлы?

ну вот так например:
Код:
T& function (T& element, node* root)
{
    if (root -> element == element) return root->element;
    function(element, root -> left);
    function(element, root -> right);
};
Kukurudza вне форума Ответить с цитированием
Старый 23.06.2011, 09:49   #2
Сtrl
C++
Форумчанин
 
Аватар для Сtrl
 
Регистрация: 27.03.2011
Сообщений: 803
По умолчанию

Поскольку у вас только один процесс, то по сути именно это и произойдет.
Ищете информацию по C++?
cplusplus.com
Сtrl вне форума Ответить с цитированием
Старый 23.06.2011, 10:17   #3
Kukurudza
Форумчанин
 
Регистрация: 02.06.2011
Сообщений: 282
По умолчанию

действительно так и происходит. вернее те узлы которые еще не вызывались, уже и не вызовутся, а те уровни функций которые были вызваны но еще не завершили свое выполнение выполнятся до конца, но уже не будут вызывать внутри себя себя же. верно? вроде правильно изъяснился.
Kukurudza вне форума Ответить с цитированием
Старый 23.06.2011, 10:53   #4
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Хм, а компилятор не ругается, что значение возвращается не при всех ситуациях? Вообще-то должен.
А как выйти - при обнаружении генерируйте исключение, которое обрабатывайте ниже. См., например, у Страуструпа главу 14.5 "Исключения, не являющиеся ошибками".
Это будет эффективно, однако этот момент необходимо развернуто прокомментировать, т.к. в данном случае исключения выполняют не ту роль, для которой предназначены - сообщение об ошибке.
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 23.06.2011, 12:01   #5
An1ka
C++,DirectX/OpenGL
Форумчанин
 
Регистрация: 09.01.2011
Сообщений: 422
По умолчанию

Цитата:
Сообщение от Kukurudza Посмотреть сообщение
такой вопрос.
проверяю рекурсивно все узлы бинарного дерева на наличие некоторого элемента, чтобы потом его изменить по ссылке. если этот элемент обнаружен как выйти из рекурсии сразу же после это, не просматривая все остальные узлы?

ну вот так например:
Код:
T& function (T& element, node* root)
{
    if (root -> element == element) return root->element;
    function(element, root -> left);
    function(element, root -> right);
};
Он не будет работать корректно. Только, если найдет в самом первом элементе. Для последующих вызовов функций нету возврата.

Код:
T& function (T& element, node* root)
{
    if (!root) return 0; // Чтобы по нулевому указателю не было обращения
    T *el = 0;
    if (root -> element == element) el = &root->element;
    if ( !el)
	el = &function(element, root -> left);
    if ( !el)
        el = &function(element, root -> right);
    return *el;
};
Как только элемент найдется, то произойдет присвоение адреса указателю, а следующих вызовов не будет и произойдет возврат. То тут еще надо предусмотреть, если элемент не будет найден вообще, а ветвь дерева закончилась. Например, если указатели left или right не указывают на следующий элемент, то их значение должно быть 0, это нужно, чтобы сделать проверку на 0 и не пойти по неправильным указателям.
An1ka вне форума Ответить с цитированием
Старый 23.06.2011, 12:16   #6
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

An1ka,
Код:
if (!root) return 0;
Так делать нехорошо, так как возвращается ссылка, т.е. должен быть конкретный объект, а не константа.

Цитата:
Сообщение от Гром
Хм, а компилятор не ругается, что значение возвращается не при всех ситуациях? Вообще-то должен.
Ну, gcc, например, просто ворнинг пишет, а его можно и случайно пропустить)

Цитата:
Сообщение от Kukurudza
если этот элемент обнаружен как выйти из рекурсии сразу же после это, не просматривая все остальные узлы?
Первое, что пришло в голову:
Код:
T& Object; // найденный элемент

bool function (T& element, node* root) // Функция возвращает true, если в потомках что-то нашлось, иначе false
{
    if (root -> element == element){
        Object=root->element;
        return true;
    };
    // return function(element, root -> left) || function(element, root -> right); Насколько я знаю, большинство компиляторов оптимизируют логическое ИЛИ, и если первый аргумент - true, то второй не вычисляется. На всякий случай далее код, который сработает таким же образом
    if(function(element,root->left)) return true; else return function(element,root->right);
};
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нерекурсивные\Рекурсивные процедуры и функции Kerragin Помощь студентам 4 03.06.2011 17:50
Рекурсивные функции NiaSpa Помощь студентам 3 04.03.2010 11:53
Рекурсивные функции. Geg[C/c++] Общие вопросы C/C++ 2 11.10.2009 11:28