Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на C / C++


РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты в разделе

Коцюрбенко Алексей aka Жерар
Статус: Мастер-Эксперт
Рейтинг: 373
∙ повысить рейтинг »
solowey
Статус: 4-й класс
Рейтинг: 150
∙ повысить рейтинг »
Степанов Иван /REDDS
Статус: 4-й класс
Рейтинг: 124
∙ повысить рейтинг »

∙ С / С++

Номер выпуска:1895
Дата выхода:20.12.2016, 19:45
Администратор рассылки:Андрей Кузнецов aka Dr_Andrew (Старший модератор)
Подписчиков / экспертов:23 / 16
Вопросов / ответов:1 / 1

Консультация # 190300: Уважаемые эксперты! Пожалуйста, ответьте на вопрос: Реализуйте класс, представляющий понятие "двоичное дерево поиска". Протестируйте его работу. Почему 2 функции?

Консультация # 190300:

Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Реализуйте класс, представляющий понятие "двоичное дерево поиска". Протестируйте его работу.
Почему 2 функции?

template <typename T>
void Bintree<T>::insert(Node* &xx, T k) {
	Node *z = new Node(k);
	if (xx == nullptr) { //если дерева нет то формируем корень
		xx = z;
		xx->parent = xx->left = xx->right = nullptr;
		return;
	}
	Node *x = xx;
	while (x != nullptr) {
		if (z->key > x->key) {
			if (x->right != nullptr) x = x->right;
			else {
				z->parent = x;
				x->right = z;
				break;
			}
		}
		else if (z->key < x->key) {
			if (x->left != nullptr) x = x->left;
			else {
				z->parent = x;
				x->left = z;
				break;
			}
		}
	}
}


Почему тут 2 функции:

template <typename T>
void Bintree<T>::insert(T k) {//вставка
    insert(head, k);
}
 
template <typename T>
void Bintree<T>::insert(Node* &xx, T k) {
    Node *z = new Node(k);
    if (xx == nullptr) { //если дерева нет то формируем корень
        xx = z;
        xx->parent = xx->left = xx->right = nullptr;
        return;
    }
    Node *x = xx;
    while (x != nullptr) {
        if (z->key > x->key) {
            if (x->right != nullptr) x = x->right;
            else {
                z->parent = x;
                x->right = z;
                break;
            }
        }
        else if (z->key < x->key) {
            if (x->left != nullptr) x = x->left;
            else {
                z->parent = x;
                x->left = z;
                break;
            }
        }
    }
}


и тут:

template <typename T>
void Bintree<T>::show() {
    show(head, 20);
}
 
template <typename T>//показываем элементы дерева
void Bintree<T>::show(Node* head, int sp) {
    if (head == nullptr) return;
    show(head->right, sp + 5);
    for (int i = 0; i < sp; ++i) std::cout << ' ';
    std::cout << head->key << std::endl; 
    show(head->left, sp + 5);
}


можете объяснить?

Дата отправки: 15.12.2016, 19:33
Вопрос задал: Посетитель - 399158 (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, Посетитель - 399158!
Вот Вам программа на основе приведенного кода.
В данной программе для вывода используется рекурсия, поэтому задавать текущий узел параметром
необходимо, но тогда вызываемую функцию с параметрами необходимо определить, как private
Удаление дерева тоже реализовано рекурсивно, поэтому сделано аналогично

Для вставки передавать корень параметром необходимости нет.
Показано, как задавать параметр по-умолчанию.
Кое-что подправил, прокомментировал

#include <iostream>

using namespace std;

#define	nullptr 0

struct Node
{
	int		key;
	Node	*left;
	Node	*right;
	Node	*parent;
};

template<class T>
class Bintree
{
public:
	//конструктор
	Bintree<T>(){head = nullptr;};

	//деструктор
	~Bintree(void);	

	//вставка
	void insert(T k);

	//вывод
	void show(int sp=20);

private:
	Node*	head;
	void FreeNode(Node *node);
	void show(Node *node, int sp);
};

template<class T>
void Bintree<T>::FreeNode(Node *node)
{
	if (node)
	{
		Bintree::FreeNode(node->left);	//левого потомка
		Bintree::FreeNode(node->right);	//правого потомка
		delete node;					//память самого узла
	}
}

template<class T>
Bintree<T>::~Bintree()
{
	Bintree<T>::FreeNode(head);
}

template <typename T>
void Bintree<T>::insert(T k) 
{
	Node *z = new Node;			//создаем новый узел
	z->key = k;					//ключ
	z->left = z->right = nullptr; //обнулим указатели на потомков

	if (head == nullptr)		//был ли корень?
	{							//если дерева нет то формируем корень
		z->parent = nullptr;	//у корня родителя нет
        head = z;				//сохраним как корень
    }
	else
	{
		Node *x = head;			//начинаем обход с корня
		while (1)				//по всем узлам
		{
			if (z->key > x->key) //если ключ нового узла больше текущего
			{
				if (x->right != nullptr)//и если правый потомок непустой
					x = x->right;		//то правого потомка делаем текущим
				else 
				{						//правый пустой
					z->parent = x;		//текущий для нового будет родителем
					x->right = z;		//а правым потомком текущего станет новый
					break;				//новый узел вставлен в дерево - выходим из цикла
				}
			}
			else if (z->key < x->key) //если ключ нового узла меньше текущего
			{
				if (x->left != nullptr) //и левый потомок непустой
					x = x->left;		//то левого потомка делаем текущим
				else 
				{						//левый пустой
					z->parent = x;		//текущий для нового будет родителем
					x->left = z;		//а левым потомком текущего станет новый
					break;				//новый узел вставлен в дерево - выходим из цикла
				}
			}
			else
			{
				delete z;				//если равно, то удалим созданный узел (игнорируем!)
				break;					//и выходим из цикла
			}
		}
	}
}

template <typename T>	//показываем элементы дерева
void Bintree<T>::show(int sp) 
{
	Bintree<T>::show(head, sp);
}

template <typename T>	//показываем элементы дерева
void Bintree<T>::show(Node *node, int sp=20) 
{
    if (node == nullptr) 
		return;
    show(node->right, sp + 5);
    for (int i = 0; i < sp; ++i) cout << ' ';
    cout << node->key << endl; 
    show(node->left, sp + 5);
}

int main()
{
	Bintree<int> tree;	//создаем класс
	tree.insert(5);		//вставим несколько узлов
	tree.insert(3);
	tree.insert(7);
	tree.insert(6);
	tree.show();		//выведем с позиции 20 (по умолчанию)
	tree.insert(4);		//добавим еще несколько узлов
	tree.insert(8);
	tree.show(0);		//выведем с 0 позиции
	tree.insert(8);		//пытаемся добавить узел с существующим ключом
	tree.show(0);		//выводим
	return 0;
}

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 16.12.2016, 13:50
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!


В избранное