const int N=4; //Количество элементов в одном квадрате
struct element
{
int keyX; //Ключ 1
int keyY; //Ключ 2
char *info; //Информация
};
//Узел дерева
struct Node
{
int minX; //Нижняя граница X
int maxX; //Верхняя граница X
int minY; //Нижняя граница Y
int maxY; //Верхняя граница Y
Node *child[4]; //Массив указателей на поддеревья
element *inf[N];//Массив указателей на элементы
};
#include <cstdlib>
#include <cstring>
#include <stdexcept>
#include <iostream>
#include <locale>
using namespace std;
// Элемент таблицы
class element
{
public:
// Конструкторы
element(int keyX, int keyY, const char* const info);
element(const element& e);
// Деструктор
~element();
// Оператор присваивания
const element & operator=(const element& e);
// Ключи
int keyX() const;
int keyY() const;
// Данные
const char* info() const;
private:
// Копируют аргумент в члены класса
void copy(const element& e);
void copy(const char* const s);
// Освобождает ресурсы
void destroy();
int _keyX;
int _keyY;
char* _info;
};
// Узел таблицы
class node
{
public:
// Конструктор
node(int minX, int maxX, int minY, int maxY);
~node();
// Обход всех элементов дерева с вызовом для каждого заданной функции
void for_each(void (*func)(int keyX, int keyY, const char* info));
protected:
// Добавление элемента
void add(const element& item);
// Поиск элемента
const element * find(int keyX, int keyY) const;
// Количество ветвей
static const size_t _CHILD_NUM = 4;
// Количество данных
static const size_t _INF_NUM = 4;
int _minX, _maxX;
int _minY, _maxY;
node* _child[_CHILD_NUM];
size_t _childNum;
element* _inf[_INF_NUM];
size_t _infNum;
private:
node(const node&);
const node & operator=(const node&);
};
class table : public node
{
public:
explicit table(int minX = 0, int maxX = 100, int minY = 0, int maxY = 100);
~table();
// Добавляет элемент в таблицу
void add(int keyX, int keyY, const char* const info);
// Поиск элемента
const char* find(int keyX, int keyY) const;
private:
table(const table&);
const table & operator=(const table&);
};
void find(const table& t, int keyX, int keyY)
{
const char* res = t.find(keyX, keyY);
cout << "Поиск для ключей [" << keyX << "," << keyY << "]: ";
if (res)
{
cout << res;
}
else
{
cout << "не найдено.";
}
cout << endl;
}
void print(int keyX, int keyY, const char* info)
{
cout << "[" << keyX << "," << keyY << "]:" << info << endl;
}
int main()
{
locale::global(locale(""));
table myTable;
myTable.add(1, 2, "1,2");
myTable.add(5, 7, "5,7");
myTable.add(8, 3, "8,3");
myTable.add(12, 22, "12,22");
myTable.add(10, 2, "10,2");
myTable.add(5, 6, "5,6");
myTable.add(2, 2, "2,2");
find(myTable, 20, 30);
find(myTable, 5, 7);
find(myTable, 2, 2);
cout << "Таблица:" << endl;
myTable.for_each(print);
#ifdef _WIN32
system("pause");
#endif
return (EXIT_SUCCESS);
}
element::element(int keyX, int keyY, const char* const info)
: _keyX(keyX)
, _keyY(keyY)
, _info(0)
{
copy(info);
}
element::element(const element& e)
: _keyX(e._keyX)
, _keyY(e._keyY)
, _info(0)
{
copy(e._info);
}
element::~element()
{
destroy();
}
const element& element::operator =(const element& e)
{
if (&e != this)
{
copy(e);
}
return *this;
}
inline int element::keyX() const
{
return _keyX;
}
inline int element::keyY() const
{
return _keyY;
}
inline const char* element::info() const
{
return _info;
}
void element::copy(const element& e)
{
destroy();
_keyX = e._keyX;
_keyY = e._keyY;
copy(e._info);
}
void element::copy(const char* const s)
{
if (s)
{
size_t size = strlen(s) + 1;
_info = new char[size];
strcpy(_info, s);
}
}
void element::destroy()
{
if (_info)
{
delete [] _info;
_info = 0;
}
}
node::node(int minX, int maxX, int minY, int maxY)
: _minX(minX)
, _maxX(maxX)
, _minY(minY)
, _maxY(maxY)
, _childNum(0)
, _infNum(0)
{
for (size_t i = 0; i < _CHILD_NUM; ++i)
{
_child[i] = 0;
}
for (size_t i = 0; i < _INF_NUM; ++i)
{
_inf[i] = 0;
}
}
node::~node()
{
for (size_t i = 0; i < _childNum; ++i)
{
if (_child[i])
{
delete _child[i];
_child[i] = 0;
}
}
for (size_t i = 0; i < _infNum; ++i)
{
if (_inf[i])
{
delete _inf[i];
_inf[i] = 0;
}
}
}
void node::for_each(void (*func)(int, int, const char*))
{
for (size_t i = 0; i < _infNum; ++i)
{
func(_inf[i]->keyX(), _inf[i]->keyY(), _inf[i]->info());
}
for (size_t i = 0; i < _childNum; ++i)
{
_child[i]->for_each(func);
}
}
void node::add(const element& item)
{
// Проверка границ
if (_minX <= item.keyX() && item.keyX() < _maxX && _minY <= item.keyY() && item.keyY() < _maxY)
{
// Если есть куда вставлять
if (_infNum < _INF_NUM)
{
_inf[_infNum++] = new element(item);
}
else
{
// Перебираем ветви
for (size_t i = 0; i < _childNum; ++i)
{
try
{
_child[i]->add(item);
return;
}
catch (invalid_argument&)
{
}
}
// Если еще не вставлен смотрим есть ли куда отрастить ветвь
if (_childNum < _CHILD_NUM)
{
// Разбиваем квадрат согласно условия
int midX = (_minX + _maxX) / 2;
int midY = (_minY + _maxY) / 2;
int minX, maxX, minY, maxY;
if (item.keyX() < midX)
{
minX = _minX;
maxX = midX;
}
else
{
minX = midX;
maxX = _maxX;
}
if (item.keyY() < midY)
{
minY = _minY;
maxY = midY;
}
else
{
minY = midY;
maxY = _maxY;
}
// Выделяем память и добавляем
node* n = new node(minX, maxX, minY, maxY);
n->add(item);
_child[_childNum++] = n;
}
else
{
throw logic_error("Не могу разместить элемент");
}
}
}
else
{
throw invalid_argument("Ключ не попадает в диапазон значений для узла");
}
}
const element * node::find(int keyX, int keyY) const
{
// Проверка границ
if (_minX <= keyX && keyX < _maxX && _minY <= keyY && keyY < _maxY)
{
// Ищем в своих данных
for (size_t i = 0; i < _infNum; ++i)
{
if (_inf[i]->keyX() == keyX && _inf[i]->keyY() == keyY)
{
return _inf[i];
}
}
// Ищем в ветвях
for (size_t i = 0; i < _childNum; ++i)
{
const element* e = _child[i]->find(keyX, keyY);
if (e)
{
return e;
}
}
}
return 0;
}
table::table(int minX, int maxX, int minY, int maxY)
: node(minX, maxX, minY, maxY)
{
}
table::~table()
{
}
void table::add(int keyX, int keyY, const char* const info)
{
node::add(element(keyX, keyY, info));
}
const char* table::find(int keyX, int keyY) const
{
const element* e = node::find(keyX, keyY);
return e ? e->info() : 0;
}
Поиск для ключей [20,30]: не найдено.
Поиск для ключей [5,7]: 5,7
Поиск для ключей [2,2]: 2,2
Таблица:
[1,2]:1,2
[5,7]:5,7
[8,3]:8,3
[12,22]:12,22
[10,2]:10,2
[5,6]:5,6
[2,2]:2,2
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.