C ++ estructura de datos de árbol --Trie

estructura específica árbol Trie su propia búsqueda, según el siguiente justo entender que parte de mi propia.

①Trie árbol es más de un árbol, a continuación, administrar el nodo secundario de gran ayuda para el rendimiento del árbol, para los fines generales, que utiliza la estructura de árbol rojo-negro como una estructura de gestión nodo hijo. Por supuesto, si está buscando cadena de Inglés o algo así, puede utilizar una matriz o hash.

②Trie árbol es un árbol de prefijo, fácil de tratar prefijos, sufijos mí en este caso no será procesada.

③Trie árbol debe no sólo a los nodos de borrado, por lo que no proporcionan una función de eliminación única modificación disponibles.

 

Sobre el Trie mi aplicación:

① Con el fin de reducir la copia de la matriz, cada nodo utilizando una estructura de árbol rojo-negro (Mapa) para sostener el nodo secundario, donde el valor de la sub-nodo como el valor clave, como un valor de puntero nodo hijo, pero no almacena el valor del nodo hijo.

② Intuitivamente, árbol Trie se transforma en la forma de clave-valor y las necesidades clave para ser iterativo. Al insertar la nueva cadena, la clave necesidad iterador al valor iteración como el valor del nodo, el último nodo al valor iterativo, valor almacenado, el nodo intermedio no almacena el valor de iteración. Cuando se determina si hay una cadena, la clave de entrada, el nodo determinando si para iterar el valor obtenido se puede almacenar.

③ inserción para crear no existe, modificar presencia.

④ proporcionar una función de búsqueda de prefijo.

 

Aquí está el código de C ++:

Entorno de compilador: GCC 7.3, VS 2005

#ifndef __TRIE_TREE_H__
#define __TRIE_TREE_H__

#if __cplusplus >= 201103L
#include <type_traits> // std::forward、std::move
#endif

#if __cplusplus >= 201103L
#define null nullptr
#else
#define null NULL
#endif 

#include <map>

template<typename _Tp>
struct Comparator
{
	int operator()(const _Tp &a1, const _Tp &a2) const
	{ return a1 < a2; }
};

template<typename _KeyType, 
typename _ValueType,
typename _CompareType = Comparator<_KeyType> >
class TrieTree
{
public:
	typedef _KeyType    key_type;
	typedef _ValueType  value_type;
	typedef const _KeyType & const_reference;

public:
	struct TTreeNode;
	typedef std::map<_KeyType, TTreeNode*, _CompareType>  container_type;

public:
	struct TTreeNode
	{
		typedef _ValueType*   pointer;
		typedef unsigned long size_type;

		typedef TTreeNode self;

		TTreeNode(pointer p = null)
			: _M_value(p) { }

		TTreeNode(const self &) { }

#if __cplusplus >= 201103L
		TTreeNode(self &&node)
			: _M_children(std::move(node._M_children)), _M_value(node._M_value)
		{ node._M_value = null; }
#endif

		~TTreeNode()
		{
			typename container_type::iterator it = _M_children.begin();
			while(it != _M_children.end())
			{ delete (it++)->second; }
			if(null != _M_value)
			{ delete _M_value; }
		}

		self* child(const key_type &v)
		{ 
			typename container_type::iterator found = _M_children.find(v);
			return found != _M_children.end() ? found->second : null;
		}

		size_type child_size() const 
		{ return static_cast<size_type>(_M_children.size()); }

		self* append_child(const key_type &v)
		{ 
			typename container_type::iterator found = _M_children.find(v);
			return found == _M_children.end() ? (_M_children[v] = new self()) : found->second;
		}

		pointer value() const
		{ return _M_value; }

		container_type _M_children;
		pointer        _M_value;
	};

public:
	typedef TTreeNode  node_type;
	typedef TTreeNode* node_pointer;

	typedef TrieTree<_KeyType, _ValueType, _CompareType> self;

public:
	TrieTree() { }

	TrieTree(const self &) { }

#if __cplusplus >= 201103L 
	TrieTree(self &&tree)
		: _M_root(std::move(tree._M_root)) { }

	template<typename _ForwardIterator, typename ... Args>
	TrieTree(_ForwardIterator b, _ForwardIterator e, Args && ... args)
	{ insert(b, e, std::forward<Args>(args)...); }

	template<typename _ForwardIterator, typename ... Args>
	node_pointer insert(_ForwardIterator b, _ForwardIterator e, Args && ... args)
	{
		if(b == e)
		{ return null; }

		node_pointer node = &_M_root;
		while(b != e)
		{ node = node->append_child(*b++); }

		node->_M_value = new value_type(std::forward<Args>(args)...);
		return node;
	}

	template<typename _Type, typename ... Args>
	node_pointer insert(const _Type &key_list, Args && ... args)
	{ return insert(key_list.begin(), key_list.end(), std::forward<Args>(args)...); }

	template<typename _Type>
	node_pointer insert(const _Type &key_list, value_type &&v)
	{ return insert(key_list.begin(), key_list.end(), std::move(v)); }

#else
	template<typename _ForwardIterator>
	TrieTree(_ForwardIterator b, _ForwardIterator e, const value_type &v)
	{ insert<_ForwardIterator>(b, e, v); }

	template<typename _ForwardIterator>
	node_pointer insert(_ForwardIterator b, _ForwardIterator e, const value_type &v)
	{
		if(b == e)
		{ return null; }

		node_pointer node = &_M_root;
		while(b != e)
		{ node = node->append_child(*b++); }

		node->_M_value = new value_type(v);
		return node;
	}

#endif
	template<typename _Type>
	node_pointer insert(const _Type &key_list, const value_type &v)
	{
		typedef typename _Type::const_iterator __citer;
		return insert<__citer>(key_list.begin(), key_list.end(), v);
	}

	template<typename _ForwardIterator>
	bool contain(_ForwardIterator b, _ForwardIterator e)
	{
		if(b == e)
		{ return false; }

		node_pointer node = &_M_root;
		while(b != e)
		{ 
			node = node->child(*b++); 

			if(null == node)
			{ return false; }
		}

		return null != node;
	}

	template<typename _ForwardIterator>
	bool contain(_ForwardIterator b, _ForwardIterator e) const 
	{ return const_cast<self*>(this)->contain<_ForwardIterator>(b, e); }

	template<typename _Type>
	bool contain(const _Type &key_list)
	{
		typedef typename _Type::const_iterator __citer;
		return contain<__citer>(key_list.begin(), key_list.end());
	}
	template<typename _Type>
	bool contain(const _Type &key_list) const
	{ return const_cast<self*>(this)->contain<_Type>(key_list); }

	template<typename _ForwardIterator>
	node_pointer find(_ForwardIterator b, _ForwardIterator e)
	{
		if(b == e)
		{ return null; }

		node_pointer node = &_M_root;
		while(b != e)
		{ 
			node = node->child(*b++); 

			if(null == node || (node->child_size() == 0 && null == node->_M_value))
			{ return null; }
		}

		if(null == node->_M_value)
		{ return null; }

		return node;
	}

	template<typename _ForwardIterator>
	const node_pointer find(_ForwardIterator b, _ForwardIterator e) const
	{ return const_cast<self*>(this)->find<_ForwardIterator>(b, e); }

	template<typename _Type>
	node_pointer find(const _Type &key_list)
	{
		typedef typename _Type::const_iterator __citer;
		return find<__citer>(key_list.begin(), key_list.end());
	}

	template<typename _Type>
	const node_pointer find(const _Type &key_list) const
	{ return const_cast<self*>(this)->find<_Type>(key_list); }

	template<typename _ForwardIterator>
	bool exists(_ForwardIterator b, _ForwardIterator e) const 
	{ return null != const_cast<self*>(this)->find<_ForwardIterator>(b, e); }

	template<typename _Type>
	bool exists(const _Type &key_list) const 
	{ 
		typedef typename _Type::const_iterator __citer;
		return exists<__citer>(key_list.begin(), key_list.end()); 
	}

	template<typename _Type>
	node_pointer operator[](const _Type &key_list)
	{ return find<_Type>(key_list); }

	value_type& value(node_pointer p)
	{ return *p->value(); }

private:
	node_type _M_root;
};

#endif // __TRIE_TREE_H__

Código de ensayo:

#include <iostream>
#include <string>
#include <cstring>
#include "trie_tree.h"

static std::string shield[] = 
{
	"aaaa",
	"aaaaabbbbbb",
	"a*b*c*d"
};

static const char *check[] = 
{
	"aaa",
	"aaaaabbbbbb",
	"b"
};

static void func2()
{
	typedef TrieTree<char, bool> tree;

	// 屏蔽字测试

	tree t;
	for(std::size_t i = 0; i < sizeof(shield) / sizeof(std::string); ++i)
	{
		t.insert<std::string>(shield[i], true);
	}

	std::cout << std::boolalpha;
	for(std::size_t i = 0; i < sizeof(check) / sizeof(const char *); ++i)
	{
		std::cout << "\"" << check[i] << "\" is shield? : " << t.exists<const char*>(check[i], check[i] + strlen(check[i])) << std::endl;
	}
}

static void func()
{
	typedef TrieTree<char, bool> tree;

	const char *ch = "aadfasf";
	const char *str = "aad";
	std::string tmp = ch;
	tree t;
	t.insert<std::string>(tmp, true);

	if(t.exists<std::string>(tmp))
	{
		std::cout << "exists11111111" << std::endl;
		tree::node_pointer p = t.find<std::string>(tmp);
		std::cout << std::boolalpha << "value: " << t.value(p) << std::endl;
	}
	if(t.exists<const char*>(ch, ch + strlen(ch)))
	{
		std::cout << "exists222222" << std::endl;
	}

	if(t.exists<const char *>(str, str + strlen(str)))
	{
		std::cout << "exists33333" << std::endl;
	}

	if(t.contain<const char *>(str, str + strlen(str)))
	{
		std::cout << "contain" << std::endl;
	}
}


int main() 
{
	func();
	func2();
	system("pause");
	return 0;
}

Los resultados son los siguientes:

Publicado 22 artículos originales · ganado elogios 3 · Vistas 3939

Supongo que te gusta

Origin blog.csdn.net/qq811299838/article/details/104765330
Recomendado
Clasificación