Как создать функцию, которая возвращает наименьшее значение неупорядоченного двоичного дерева
Кажется, это должно быть действительно легко, но у меня были проблемы с этим в течение достаточно долгого времени. Как видно из заголовка, я просто пытаюсь найти узел в двоичном дереве (не BST!) С наименьшим значением и вернуть его. Я могу довольно легко написать рекурсивную функцию void, которая может по крайней мере назначить наименьшее значение в функции, но я застрял в том, как отследить предыдущие узлы, как только я достигну указателя NULL.
У меня есть класс узла, который имеет указатель на левый и правый дочерний элемент, каждый со своим собственным значением. Вот моя (неудачная) попытка:
int preOrder(Node *node, int value, int count, int sizeOfTree)
{
count++; //keeps track of whether or not we have traversed the whole tree
if(value < node->getValue())
value = node->getValue();
if(count == sizeOfTree);
return value;
if(node == NULL)
//Want to return to the previous function call
//How do I do this for a non void function?
//for a void function, you could jsut type "return;" and the function
//back tracks to your previous place in the tree
//but since I'm returning a value, How would I go about doing this?
//these 2 calls are incorrect but the idea is that I first traverse the left subtree
//followed by a traversal of the right subtree.
preOrder(node->getLeft(), value);
preOrder(node->getRight(), value);
}
Если возможно, я хотел бы попытаться сделать это без учета "счета", чтобы сделать код чище. Дайте мне знать, если потребуется больше разъяснений.
3 ответа
Я не очень понимаю, почему в исходном коде вам нужно отслеживать количество пройденных элементов. Вот мое решение:
int find_min(Node* node)
{
int value = node->getValue()
Node* left_node = node->getLeft();
if (left_node != NULL)
{
int left_value = find_min(left_node);
if (left_value < value)
value = left_value;
}
Node* right_node = node->getRight();
if (right_node != NULL)
{
int right_value = find_min(right_node);
if (right_value < value)
value = right_value;
}
return value;
}
По сути, вам нужно просто посетить каждый узел и отследить наименьшее значение, которое вы видели. Это может быть сделано довольно просто:
#include <algorithm>
#include <limits>
int preOrder(Node *node)
{
if(node == NULL) return std::numeric_limits<int>::max();
// this should never affect the calculation of the minimum
// (What could possibly be bigger than INT_MAX? At worst it's equal)
int value = std::min(
node->getValue(),
preOrder(node->getLeft())
);
value = std::min(
value,
preOrder(node->getRight())
);
return value;
}
Итак, у вас есть неупорядоченное двоичное дерево, и вы пытаетесь найти в нем самый низкий элемент.
Поскольку дерево неупорядочено, самый нижний элемент может находиться в любой позиции дерева, поэтому вы должны выполнить поиск по всему дереву.
Характеристики поиска будут следующими:
- тщательный (все дерево ищется)
- рекурсивный (а не итеративный, что было бы действительно противно)
- базовый случай: узел равен NULL
- базовый результат: поддерживать текущую стоимость
Давайте напишем это тогда:
#include <algorithm>
using namespace std;
int searchLowest(Node * node, int value = INT_MAX)
{
if (node == NULL) // base case
return value; // base outcome
// at this point, node must not be NULL
value = min(value, preOrder(node->getRight(), value)); // thorough, always recurse
value = min(value, preOrder(node->getLeft (), value)); // and check children
value = min(value, node->getValue());
return value;
}
Редактировать для тщательности, справедливости и OOness:
// Node.h
#include <algorithm>
using namespace std;
template <typename T>
class Node
{
public:
Node(T item)
{
data = item;
}
T lowest()
{
T value = data;
if (right != NULL)
value = min(value, right->lowest());
if (left != NULL)
value = min(value, left->lowest());
return value;
}
Node<T> * getRight()
{
return right;
}
Node<T> * getLeft()
{
return left;
}
private:
T data;
Node<T> * right;
Node<T> * left;
};
// main.cpp
#include <iostream>
#include "Node.h"
using namespace std;
int main(int c, char * v[])
{
Node<int> * tree = sycamore(); // makes a nice big tree
cout << tree->lowest();
}