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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> удаление поддерева 
V
    Опции темы
toxx
Дата 28.3.2010, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Есть n-мерное дерево
Код

struct Tree
{
    int d;
    int count;
    vector<Tree *> Trees;
};

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



Это сообщение отредактировал(а) toxx - 28.3.2010, 21:50
PM MAIL   Вверх
bsa
Дата 28.3.2010, 21:53 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Нет, если ты пользуешься указателями, то ничего никуда копировать не надо. Тем более, что у тебя вектор. Просто в деструкторе Tree напиши корректное уничтожение всех поддеревьев (delete tree), а когда нужно удалить конкретное поддерево, то просто применяй к нему delete и erase к Trees.
PM   Вверх
toxx
Дата 28.3.2010, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(bsa @ 28.3.2010,  21:53)
Нет, если ты пользуешься указателями, то ничего никуда копировать не надо. Тем более, что у тебя вектор. Просто в деструкторе Tree напиши корректное уничтожение всех поддеревьев (delete tree), а когда нужно удалить конкретное поддерево, то просто применяй к нему delete и erase к Trees.

Нашел как пользоваться erase, но почемуто, использовал find чтобы значеие было итератор,но он отказывается работать...
Код

void deleteT(Tree *root,int level)
{
    Tree* pv=root,*prev=root;
    Tree* pTree;
    if(level==dLevel) 
    {
        vector<Tree*>::iterator it;
        it=find(prev->Trees.begin(),prev->Trees.end(),dItem);
        prev->Trees.remove(it);

    }
    if(root)
    {
        for(int i=0;i<prev->Trees.size();i++)
        if(prev->count%2!=0) 
        {
            cout<<"i= "<<i<<" prev->Trees.size()= "<<root->Trees.size()<<endl;
            dLevel=level-1;
            dItem=i;
            delete root;
            root=NULL;
        }
        else deleteT(root->Trees[i],level+1);
    }
}

PM MAIL   Вверх
bsa
Дата 28.3.2010, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



toxx, для вектора можно использовать операцию сложения результата метода begin() и индекса, для получения итератора на нужный элемент. Но лучше использовать std::advance()
PM   Вверх
toxx
Дата 29.3.2010, 00:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(bsa @ 28.3.2010,  23:53)
toxx, для вектора можно использовать операцию сложения результата метода begin() и индекса, для получения итератора на нужный элемент. Но лучше использовать std::advance()

хмм хорошо понятно, а если я изменю структуру так
Код

struct Tree
{
    int d;
    int count;
    Tree** Trees;
};


У меня уже будет не вектор(массив указателей), если мне нужно будет выполнить эту же задачу,
то мне также не нужно будет копировать указатели?т.е. простое перемещение указателей
например я нашел отца(у него нашел сына которого удалили delete'ом):
Код

prev->Trees[i-1]=prev->Trees[i];

Я просто также сделал для вектора у меня была такая картина:
                                     10
                                   /     \
                               21      22
                             /
                           31
после удаления 
                                     10
                                   /     \
                        -172302     22


Это сообщение отредактировал(а) toxx - 29.3.2010, 00:36
PM MAIL   Вверх
xvr
Дата 29.3.2010, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Прежде, чем писать код, надо очень хорошо представлять себе алгоритм, который ты пытаешься реализовать. У тебя в коде написано непонятно что  smile 
Кто такие dLevel и dItem? Что за загадочный if(prev->count%2!=0) в цикле? Что такое вообще count в узле дерева?
И что именно надо удалять - все поддерево или отдельный узел?

PM MAIL   Вверх
toxx
Дата 29.3.2010, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(xvr @ 29.3.2010,  13:44)
Прежде, чем писать код, надо очень хорошо представлять себе алгоритм, который ты пытаешься реализовать. У тебя в коде написано непонятно что  smile 
Кто такие dLevel и dItem? Что за загадочный if(prev->count%2!=0) в цикле? Что такое вообще count в узле дерева?
И что именно надо удалять - все поддерево или отдельный узел?

Я просто хотел спросить в общем)

У меня есть задача удалить поддеревья где нечетное число листьев т.е.:
Код

struct Tree
{
    int d; // значение
    int count; // количество сыновей
    vector<Tree *> Trees; // собственно указатели на сыновей 
};


я ищу нечетное число листьев:
Код

if(prev->count%2!=0)


Далее я понял что если удалять поддерево то и у отца этого поддерева исчезнет указатель на этого сына
т.е. как я понял нужно найти уровень отца
Код

dLevel=level-1;

и собственно какой по номеру этот указатель
Код

dItem=i;

Далее я удаляю это поддерево
Код

delete root;
root=NULL;

и Когда рекурсия идет обратно она останавливается на этом уровне
Код

if(level==dLevel) 

и удаляет его...
Правильно я представляю задчу?или ошибся слегка?

Поэтому я и спрашиваю если я буду присваивание указателей отца этого поддерева так
Код

prev->Trees[i-1]=prev->Trees[i];

будет ли это верно, т.к. я читал что лучше скопировать указатели...

Это сообщение отредактировал(а) toxx - 29.3.2010, 14:04
PM MAIL   Вверх
xvr
Дата 29.3.2010, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Сделай деструктор у Tree
Код

Tree::~Tree()
{
 for(size_t i=0;i<Trees.size();++i) delete Trees[i];
}
и удаляй нужные элементы из массива Trees (сначала delete Trees[i]; потом Trees.erase(Trees.begin()+i); )

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


Опытный
**


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

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



Цитата(xvr @ 29.3.2010,  15:46)
Сделай деструктор у Tree
Код

Tree::~Tree()
{
 for(size_t i=0;i<Trees.size();++i) delete Trees[i];
}
и удаляй нужные элементы из массива Trees (сначала delete Trees[i]; потом Trees.erase(Trees.begin()+i); )

Все сделал, все работает=) Спасибо
Но я тут прочитал еще раз свое задание
Код

Удалить все поддеревья с нечётным числом листьев

У меня было дерево
       10
     /    \
  21    22
  / \       \
33 32    45
/
34
После удаления оно стало
      10
     /    \
  21    22
  / \      
33 32   

Вродебы это не правильно?(просто для себя определить верно я сделал или нет)
Чтобы сделать тоже самое но только без std::vector<>
для структуры
Код

struct Tree
{
    int d;
    int count;
    Tree** Trees;
};

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


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(toxx @  29.3.2010,  17:12 Найти цитируемый пост)
Вродебы это не правильно
Вроде правильно
Цитата

Чтобы сделать тоже самое но только без std::vector<>
Писать манипуляции с Trees вручную (перезаказ памяти под меньший размер и копирование туда оставшихся элементов)

PM MAIL   Вверх
toxx
Дата 29.3.2010, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(xvr @ 29.3.2010,  17:50)
Цитата(toxx @  29.3.2010,  17:12 Найти цитируемый пост)
Вродебы это не правильно
Вроде правильно
Цитата

Чтобы сделать тоже самое но только без std::vector<>
Писать манипуляции с Trees вручную (перезаказ памяти под меньший размер и копирование туда оставшихся элементов)





Просто меня смущает то что при вот таком вводе данных
http://www.imagepost.ru/images/88/tt.jpg

Удаляет все дерево, оставляя одну вершину...

Это сообщение отредактировал(а) toxx - 29.3.2010, 21:04
PM MAIL   Вверх
xvr
Дата 29.3.2010, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Правильно удаляет - у вершины 3 потомка, что явно число нечетное. Т.ч. поддерево удаляется. До исследования поддеревьев глубже уже дело не доходит.

PM MAIL   Вверх
bsa
Дата 29.3.2010, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



toxx, это уже проблемы задания, а не его реализации. Обратись к тому, кто это задание выдал.
PM   Вверх
toxx
Дата 29.3.2010, 22:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



xvr, bsa

Обращусь, спасибо за помощь.Задание действительно звучит двояко.
PM MAIL   Вверх
toxx
Дата 30.3.2010, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Всё-таки мне я думаю что задача состоит маленько в другом.
Как я делаю, думаю это очень просто.
Думаю из дерева нужно сделать что-то типа этого:
http://www.imagepost.ru/?v=88/tt_2.jpg

Думаю т.к.  у 2 нечетное кол-во нужно удалить ветку 2-5
аналогично 4-6-7-8
Поддеревом как я понимаю нужно считать всё кроме корня т.е. 2,3,4

В свете этого я решил сделать свой класс вектор и функцию для удаления элемента из произвольного места массива
Могу ли я применимо к указателям т.е. Vector<Tree*> выполнить удаление элементов 2,3?
Вот мой класс Vector и функция удаления erase:
Код

class Vector
{
    T* V;
    int n;
public:
    Vector(int=0);
    int size(){return n;}
    int begin(){return 0;}
    int end(){return n;}
    void resize(int);
    Vector& erase(int);
    ~Vector(){delete[] V;}
    T& operator[](int i){return V[i];}
};
template <class T>
Vector<T>::Vector(int k)
{
    n=k;
    V=new T[n];
}
template <class T>
Vector<T>& Vector<T> ::erase(int k)
{
    k-=1;
    Vector<T> buf=*this;
    for(int i=0;i<n;i++)
    {
        if(i!=k)V[i]=buf[i];
        else 
        {
            V[i]=buf[i+1];
            k++;
        }
    }
    n-=1;
    V=new T[n];
    for(int i=0;i<n;i++)
        V[i]=buf[i];
    return *this;
}
template <class T>
void Vector<T>::resize(int k)
{
    delete[] V;
    n=k;
    V=new T[n];
    for(int i=0;i<n;i++)
        V[i]=0;
}


PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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