Реализация множеств при помощи последовательностей

 

Множества можно организовать аналогичным образом. Отличие состоит лишь в упрощении структуры - отсутствует необходимость работы с объектами-значениями. Ключи вставляются в последовательность и удаляются из него по полной аналогии. Поиск также строится аналогично, однако в качестве результата интересует факт вхождения элемента в множество (истина или ложь), а не какое-либо данное-значение.

 

В основе реализации множества, приведенной ниже, лежит введенная ранее реализация односвязных списков:

 

#include "integer_set.hpp"

#include "integer_list.hpp"

 

#include <cassert>

 

// Структура-множество

structIntegerSet

{

// Внутренний список с данными

IntegerList m_data;

};

 

// Создание объекта-множества

IntegerSet * IntegerSetCreate ()

{

// Создаем объект-множество в динамической памяти

IntegerSet * pSet = newIntegerSet;

 

// Инициализируем внутренний список

IntegerListInit( pSet->m_data );

 

// Возвращаем объект во внешний код

returnpSet;

}

 

// Уничтожение объекта-множества

voidIntegerSetDestroy ( IntegerSet * _pSet )

{

// Освобождаем ресурсы внутреннего списка

IntegerListDestroy( _pSet->m_data );

 

// Уничтожаем сам объект-множество

delete_pSet;

}

 

// Очистка множества

voidIntegerSetClear ( IntegerSet & _set )

{

// Очищаем внутренний список

IntegerListClear( _set.m_data );

}

 

// Проверка множества на пустоту

boolIntegerSetIsEmpty ( constIntegerSet & _set )

{

// Множество пусто, когда пуст внутренний список

returnIntegerListIsEmpty( _set.m_data );

}

 

// Возврат количества элементов в множестве

intIntegerSetSize ( constIntegerSet & _set )

{

// Равно размеру внутреннего списка

returnIntegerListSize( _set.m_data );

}

 

// Определение принадлежности указанного ключа множеству

boolIntegerSetHasKey ( constIntegerSet & _set, int_key )

{

// Осуществляем поиск ключа с начала списка методом полного перебора

IntegerList::Node * pNode = _set.m_data.m_pFirst;

while( pNode )

{

if( pNode->m_value == _key )

// Ключ найден

return true;

pNode = pNode->m_pNext;

}

 

// Ключ не найден

return false;

}

 

// Вставка ключа во множество

voidIntegerSetInsertKey ( IntegerSet & _set, int_key )

{

// Если ключа еще нет во внутреннем списке, его следует вставить в конец списка

if( ! IntegerSetHasKey( _set, _key ) )

IntegerListPushBack( _set.m_data, _key );

}

 

// Удаление указанного ключа из множества

voidIntegerSetRemoveKey ( IntegerSet & _set, int_key )

{

// Ищем существующий узел с таким ключом

IntegerList::Node * pNode = _set.m_data.m_pFirst;

while( pNode )

{

if( pNode->m_value == _key )

{

// Удаляем найденный узел и завершаем процедуру

IntegerListDeleteNode( _set.m_data, pNode );

return;

}

pNode = pNode->m_pNext;

}

 

// Ошибка - ключа не существует в данном множестве!

assert( !"Key is unavailble!" );

}

 

// Вспомогательная функция, копирущая все элементы входного множества в другое

voidIntegerSetInsertAllKeys ( constIntegerSet & _sourceSet, IntegerSet & _targetSet )

{

// Перебираем все элементы исходного множества

IntegerList::Node * pNode = _sourceSet.m_data.m_pFirst;

while( pNode )

{

// Вставляем очередной ключ в целевое множество и движемся далее

IntegerSetInsertKey( _targetSet, pNode->m_value );

pNode = pNode->m_pNext;

}

}

 

// Объединение двух множеств - результат в третьем множестве

voidIntegerSetUnite ( constIntegerSet & _set1,

constIntegerSet & _set2,

IntegerSet & _targetSet )

{

// Очищаем целевое множество

IntegerSetClear( _targetSet );

 

// Копируем все элементы первого множества

IntegerSetInsertAllKeys( _set1, _targetSet );

 

// Копируем все элементы второго множества.

// Функция вставки ключа гарантирует,

// что повторяющиеся значения будут игнорироваться

IntegerSetInsertAllKeys( _set2, _targetSet );

}

 

// Пересечение двух множеств - результат в третьем множестве

voidIntegerSetIntersect ( constIntegerSet & _set1,

constIntegerSet & _set2,

IntegerSet & _targetSet )

{

// Очищаем целевое множество

IntegerSetClear( _targetSet );

 

// Перебираем все элементы первого множества

IntegerList::Node * pNode = _set1.m_data.m_pFirst;

while( pNode )

{

// Если выбранный элемент первого множества существует во втором,

// то вставляем его в целевое множество

if( IntegerSetHasKey( _set2, pNode->m_value ) )

IntegerSetInsertKey( _targetSet, pNode->m_value );

 

pNode = pNode->m_pNext;

}

}

 

// Разность двух множеств - результат в третьем множестве

voidIntegerSetDifference ( constIntegerSet & _set1,

constIntegerSet & _set2,

IntegerSet & _targetSet )

{

// Очищаем целевое множество

IntegerSetClear( _targetSet );

 

// Перебираем все элементы первого множества

IntegerList::Node * pNode = _set1.m_data.m_pFirst;

while( pNode )

{

// Если выбранный элемент первого множества НЕ существует во втором,

// то вставляем его в целевое множество

if( ! IntegerSetHasKey( _set2, pNode->m_value ) )

IntegerSetInsertKey( _targetSet, pNode->m_value );

 

pNode = pNode->m_pNext;

}

}

 

// Симметрическая разность двух множеств - результат в третьем множестве

voidIntegerSetSymmetricDifference ( constIntegerSet & _set1,

constIntegerSet & _set2,

IntegerSet & _targetSet )

{

// Сохраняем разницу между первым и вторым во временном множестве

IntegerSet * pTemp1 = IntegerSetCreate();

IntegerSetDifference( _set1, _set2, * pTemp1 );

 

// Сохраняем разницу между вторым и первым в другом временном множестве

IntegerSet * pTemp2 = IntegerSetCreate();

IntegerSetDifference( _set2, _set1, * pTemp2 );

 

// Объединяем результирующие множества

IntegerSetUnion( * pTemp1, * pTemp2, _targetSet );

 

// Освобождаем ресурсы временных множеств

IntegerSetDestroy( pTemp1 );

IntegerSetDestroy( pTemp2 );

}

 








Дата добавления: 2016-01-29; просмотров: 787;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.025 сек.