C ++ツリーデータ構造--Trie

特定のトライ木構造は、独自の検索には、次のようにちょうど私自身のその部分を理解して言いました。

①Trieツリーは、より一本の木よりも、その後、ツリーのパフォーマンスのための大きな助けの子ノードを管理し、一般的な目的のために、私は子ノードの管理構造として赤黒ツリー構造を使用しています。それは英語の文字列か何かを探している場合はもちろん、あなたは配列やハッシュを使用することができます。

②Trieツリーはプレフィックスツリーで、プレフィックスに対処しやすく、この場合は処理されないで私をサフィックス。

③Trieツリーだけではなく、削除ノードので、私は削除機能にのみ利用可能修正を提供していないはずです。

 

トライ私の実装について:

①子ノードポインタ値としてキー値とサブノードの値は、が、子ノードの値を格納しない、請求配列のコピーを低減するために、赤黒木構造(マップ)を使用して、各ノードは、子ノードを保持します。

②直感的に、トライ木は、反復されるキー値およびキーニーズの形に変換されます。新しい文字列を挿入する際に、ノードの値として反復値にキー必要イテレータ、反復値に最後のノード、格納された値は、中間ノードは、反復値を格納しません。それは、文字列、入力キーが存在するか否か判定された場合、得られた値を反復するかどうかを決定することによりノードを格納することができます。

③挿入は存在しません作成するには、プレゼンスを変更します。

④プレフィックス検索機能を提供します。

 

ここではC ++のコードは次のとおりです。

コンパイラ環境: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__

テストコード:

#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;
}

結果は以下の通りであります:

公開された22元の記事 ウォンの賞賛3 ビュー3939

おすすめ

転載: blog.csdn.net/qq811299838/article/details/104765330
おすすめ