Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Деревья! help :( 
V
    Опции темы
CrystalNoir
Дата 23.11.2007, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 23.11.2007

Репутация: нет
Всего: нет



Кто нибудь напишите, пожалуйста, как выглядит функция с помощью которой можно найти прошлого и следущего соседа какой нибудь вершины. Если можно то хотя бы в inorder, пожалуйста :((( 

PM MAIL   Вверх
JackYF
Дата 23.11.2007, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



CrystalNoir, ты ничего не сказал про тип дерева, его структуру и т.д.
Задай полный вопрос, а не обрывок.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
marcusmae
Дата 23.11.2007, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



CrystalNoir, что такое inorder?

дерево классического вида (значение+ссылки на листья) позволяет вершине иметь в ближнем доступе только листья, то есть связанные с ней вершины, расположенные ниже по иерархии. Чтобы получить "соседей", придётся от корня поиском добраться до вершины, имеющей данную в качестве листа (если только дерево не реализовано по-другому).


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
CrystalNoir
Дата 23.11.2007, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 23.11.2007

Репутация: нет
Всего: нет



JackYF
Цитата

ты ничего не сказал про тип дерева, его структуру и т.д.

извините - забыла :(( .. Это бинарное дерево. Например такое:
-----4
---/---\
--2----6
-/-\---/-\
1--3-5--7

Соседи корня 4 - это не 2 и 6, а 3 и 5. Но в то же время соседи вершины 2 - это 1 и 3. Как  можно найти соседей каждой вершины в инордер порядке? :((((((

marcusmae
Цитата

что такое inorder?

это один из обходов дерева, в котором сначала обходят левый лист потом вершину, потом правый лист. еще есть preorder, в котором сначала обходят вершину потом листья, и postorder, в котором идут сначала листья потом вершина..

Помогите, пожалуйста, разобраться с нахождением соседей в инордере на С++ или С :(((

PM MAIL   Вверх
marcusmae
Дата 23.11.2007, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



CrystalNoir, с Ваших слов я понял, что соседями для данной вершины в бинарном дереве являются самый правый лист левого поддерева и самый левый лист правого поддерева. Немного мест, где можно увидеть такой термин. Если это верно, то уже можно написать код, если б ещё понять, как может быть "обход листа" перед "обходом вершины", при том, что невозможно попасть в лист иначе, как через вершину.  smile

Код

struct TreeNode {
  int value;
  TreeNode *left, *right;
};


- такова ли структура Вашего дерева?


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
CrystalNoir
Дата 23.11.2007, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 23.11.2007

Репутация: нет
Всего: нет



marcusmae, я может не правильно высказалась.. 
Соседями (siblings) для данной вершины в бинарном дереве являются не самый правый лист левого поддерева и самый левый лист правого поддерева, а последняя обойденная вершина и следущая, которую надо обойти в inorder.

Цитата

-----4
---/---\
--2----6
-/-\---/-\
1--3-5--7

Соседи корня 4 - это не 2 и 6, а 3 и 5. Но в то же время соседи вершины 2 - это 1 и 3. 

Именно эти два примера я написала для того чтоб была видна разница, если у 2 соседи 1 и 3, то это не значит что у всех вершин соседи будут две вершины на уровень ниже, потому что ниже, например, той же вершины 4 ее дети 2 и 6, а надо найти предыдущего и следущего соседей в инордер порядке и у 4 они будут 3 и 5, потому что если смотреть на приведенное в пример дерево, то в инордер его обходят так: 1234567, получается что сосед каждой нужной вершины слево и с право.

Цитата

struct TreeNode {
  int value;
  TreeNode *left, *right;
};
- такова ли структура Вашего дерева? 

да, идея дерева такая, только записана с классом, но это ничего, со структурой пример я бы тоже поняла.. 
Я просто ОЧЕНЬ хочу узнать, как найти этих соседей инордер обходом :((((((
ПОЖАЛУЙСТА помогите :((
PM MAIL   Вверх
marcusmae
Дата 23.11.2007, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



CrystalNoir, я пытаюсь интерпретировать Ваше определение, потому что оно непонятно. Моя трактовка с левейшим и правейшим в поддеревьях НЕ является неправильной по крайней мере для тех двух примеров, что Вы приводите. Вот код :

Код

#include <iostream>
using namespace std;

// The tree node structure.
struct TreeNode {

    int value;
    TreeNode *left, *right;

    TreeNode(int value, TreeNode* left, TreeNode* right) {
        this->value = value;
        this->left = left; this->right = right;
    }

    ~TreeNode() { delete this->left; delete this->right; }
};

// Get the inorder lookup first node and last node in sequence.
TreeNode* GetLeftestLeaf(TreeNode* rootNode) {

    // Go downstairs to the leftest leaf and store it as the first.
    TreeNode *result =  rootNode;
    while (result->left != NULL)
        result = result->left;
    return result;
}

// Get the inorder lookup first node and last node in sequence.
TreeNode* GetRightestLeaf(TreeNode* rootNode) {

    // Go downstairs to the rightest leaf and store it as the first.
    TreeNode *result =  rootNode;
    while (result->right != NULL)
        result = result->right;
    return result;
}


int _tmain(int argc, _TCHAR* argv[])
{
    // Your tree like in topic :
    // -----4
    // ---/---\
    // --2-----6
    // -/-\---/-\
    // 1---3-5---7
    TreeNode* tree = new TreeNode(4,
        new TreeNode(2, new TreeNode(1, NULL, NULL), new TreeNode(3, NULL, NULL)),
        new TreeNode(6, new TreeNode(5, NULL, NULL), new TreeNode(7, NULL, NULL)));

    // Result for this is 3 and 5.
    cout << "Neighbours for the big tree : " <<
        GetRightestLeaf(tree->left)->value << " and " <<
        GetLeftestLeaf(tree->right)->value << endl;

    // And result for this is 1 and 3.
    cout << "Neighbours for the left subtree : " <<
        GetRightestLeaf(tree->left->left)->value << " and " <<
        GetLeftestLeaf(tree->left->right)->value << endl;

    delete tree;

    return 0;
}


Нехитрой парой циклов получаем искомые пары 3 и 5 для большого дерева и 1 и 3 - для левого поддерева. Здесь нет никакого обхода (он не нужен, вообще-то), но я готов его сделать, если вы объясните принцип обхода не на примере, а в общем. Последний Ваш пост не содержит дополнительных объяснений на этот счёт  smile

Это сообщение отредактировал(а) marcusmae - 23.11.2007, 22:24


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
SaDFromSpb
Дата 23.11.2007, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 5.4.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 3



Цитата(CrystalNoir @  23.11.2007,  21:27 Найти цитируемый пост)
Соседями (siblings) для данной вершины в бинарном дереве являются не самый правый лист левого поддерева и самый левый лист правого поддерева, а последняя обойденная вершина и следущая, которую надо обойти в inorder.

Ты знаешь, по твоему описанию это одно и тоже получается  smile 
Если полный обход твоего дерева в inorder это 1,2,3,4,5,6,7. То marcusmae понял тебя правильно и написал все верно.



--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
CrystalNoir
Дата 23.11.2007, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 23.11.2007

Репутация: нет
Всего: нет



marcusmae, спасибо Вам за ответ! Но если дерево будет в два или три раза глубже, то левейший лист с помощью GetLeftestLeaf(tree->left->right)->value не найдется..

Принцип работы инордер обхода: идти влево до самого левого листа - запомнить этот лист, поднятся на уровень выше к вершине-родителю левого листа - запомнить ее, спуститься вниз к правому листу - запомнить. Подняться опять к вершине-родителю - не запоминать. Поднятся к родителю родителя-запомнить -> спуститься в право-низ и там в таком порядке все обойти. Получается что то на подобии  левый лист-вершина-правый лист.

(A+5)*B-2*E , в этом примере сначала идет (A+5), потом это умножается на B, затем 2*E и от первого отнимают второе. Это смысл инордера, деревом это можно записать как:

-----------   -
---------- /----\
-------- *------ *
-------/---\-----/--\
----- + --  B--2---E
----/--\
---A---5


SaDFromSpb,  я не говорю что неправильно, правильно конечно, просто деревья могут быть даны абсолютно разные, с разными значениями(values). Как бы  сделать чтоб не только на конкретный пример функция работала, а на любой произвольный.. :(((((

Это сообщение отредактировал(а) CrystalNoir - 24.11.2007, 16:50
PM MAIL   Вверх
marcusmae
Дата 23.11.2007, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



Ага, ясно.

Ну, вот, можно рекурсией :

Код

// Get the inorder lookup values sequence.
void InOrderSequence(TreeNode* root) {

    // Is leaf.
    if ((root->left == NULL) && (root->right == NULL))
        cout << root->value;
    else
    {
        InOrderSequence(root->left);
        cout << root->value;
        InOrderSequence(root->right);
    }
    
}

int _tmain(int argc, _TCHAR* argv[])
{
    // Your tree lake in topic :
    // -----4
    // ---/---\
    // --2-----6
    // -/-\---/-\
    // 1---3-5---7
    TreeNode* tree = new TreeNode(4,
        new TreeNode(2, new TreeNode(1, NULL, NULL), new TreeNode(3, NULL, NULL)),
        new TreeNode(6, new TreeNode(5, NULL, NULL), new TreeNode(7, NULL, NULL)));

    // Inorder lookup sequence. Result is 1234567.
    cout << "Inorder lookup sequence : ";
    InOrderSequence(tree); 
    cout << endl;

    delete tree;

    return 0;
}


Проверьте. Сейчас придумаю, как вывести соседей.

Это сообщение отредактировал(а) marcusmae - 23.11.2007, 23:28


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
CrystalNoir
Дата 24.11.2007, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 23.11.2007

Репутация: нет
Всего: нет



marcusmae, спасибо за рекурсию! я ее проверила - выводит все вершины в инордер порядке!

Цитата

Сейчас придумаю, как вывести соседей.

пожалуйста, напишите :((((((
PM MAIL   Вверх
marcusmae
Дата 24.11.2007, 00:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



Вот какой мой окончательный вариант :

Код

#include <iostream>
using namespace std;

// The tree node structure.
struct TreeNode {

    int value;
    TreeNode *left, *right;

    TreeNode(int value, TreeNode* left, TreeNode* right) {
        this->value = value;
        this->left = left; this->right = right;
    }

    ~TreeNode() { delete this->left; delete this->right; }
};

// Get the inorder lookup values sequence.
void InOrderSequence(TreeNode* root, int* nodeIndex, int* result) {

    if ((root->left == NULL) && (root->right == NULL))
    {
        // Store the leaf value.
        result[*nodeIndex] = root->value;
        (*nodeIndex)++;
    }
    else
    {
        // Recursive lookup of the left subnode.
        InOrderSequence(root->left, nodeIndex, result);

        // Store the node value.
        result[*nodeIndex] = root->value;
        (*nodeIndex)++;

        // Recursive lookup of the right subnode.
        InOrderSequence(root->right, nodeIndex,
            result);
    }
    
}

int _tmain(int argc, _TCHAR* argv[])
{
    // Your tree like in topic :
    // -----4
    // ---/---\
    // --2-----6
    // -/-\---/-\
    // 1---3-5---7
    TreeNode* tree = new TreeNode(4,
        new TreeNode(2, new TreeNode(1, NULL, NULL), new TreeNode(3, NULL, NULL)),
        new TreeNode(6, new TreeNode(5, NULL, NULL), new TreeNode(7, NULL, NULL)));

    // Inorder lookup sequence.
    const int nodesCount = 7; // there are 7 nodes in our tree.
    int nodeIndex = 0, *inOrderSequence = new int[nodesCount];
    InOrderSequence(tree, &nodeIndex, inOrderSequence);

    cout << "Inorder tree lookup sequence : ";
    for (int index = 0; index < nodesCount; index++)
        cout << inOrderSequence[index];
    cout << endl;
    
    // Lookup for the tree root value index in the sequence array and
    // cout its neighbours.
    int rootValueIndex;
    for (rootValueIndex = 0; (rootValueIndex < nodesCount) &&
        (inOrderSequence[rootValueIndex] != tree->value); rootValueIndex++) ;
    cout << "Neighbours are : ";
    if (rootValueIndex != 0)
        cout << inOrderSequence[rootValueIndex-1] << " ";
    else
        cout << "(not present) ";
    if (rootValueIndex != nodesCount)
        cout << inOrderSequence[rootValueIndex+1];
    else
        cout << "(not present)";
    cout << endl;

    delete inOrderSequence;
    delete tree;

    return 0;
}



Это сообщение отредактировал(а) marcusmae - 24.11.2007, 00:17


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
CrystalNoir
Дата 24.11.2007, 00:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 23.11.2007

Репутация: нет
Всего: нет



marcusmae, спасибо большое! Вы мне очень помогли! smile))))
PM MAIL   Вверх
marcusmae
Дата 24.11.2007, 00:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



О, замечательно! Желаю успехов smile 


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
JackYF
Дата 24.11.2007, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



CrystalNoir, пометьте тему решённой тогда smile


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1000 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.