字典树Trie使用数值作为KEY

字典树的数据结构我就不作描述了,网上的Trie算法基本上都是基本字符串作为KEY的,字符串作为KEY每个子节点占用26 * 4个字节,对于数据量不大的情况效果不错,但对于大量数据占用内存空间消耗比较大,而使用数值作为KEY的话每个节点仅点10 * 4个字节,相对于字符串来说浪费的空间得到很大改善了。直接上代码!

template <class Type>
class CTrie
{
	struct Node
	{
		Type Val;
		bool isLeaf;	//是否叶节点
		Node *parent;
		Node *childs[10];

		Node()
		{
			isLeaf = false;
			parent = NULL;
			Val = Type();
			for (int i = 0; i < 10; i++) 
			{
				childs[i] = NULL;
			}
		}
	};

protected:
	Node	* m_root;
	size_t	m_size;

public:
	CTrie()
	{
		m_size = 0;
		m_root = new Node();
	}
	~CTrie()
	{
		clear();
		delete m_root;
	}

	//插入键值
	void insert(DWORD dwKey, const Type &Val)
	{
		if (!m_root) return;

		Node *node = m_root;
		int index;
		do
		{
			index = dwKey % 10;
			if (!node->childs[index])
			{
				node->childs[index] = new Node();
				node->childs[index]->parent = node;
			}
			node = node->childs[index];
			dwKey /= 10;
		} while (dwKey > 0);

		node->isLeaf = true;
		node->Val = Val;
		m_size++;
	}

	//键值查找
	bool find(DWORD dwKey, Type &Val)
	{
		if (!m_root) return false;

		Node *node = m_root;
		int index;
		do
		{
			index = dwKey % 10;
			node = node->childs[index];
			dwKey /= 10;
		} while (dwKey > 0 && node);

		if (node)
		{
			Val = node->Val;
			return true;
		}

		return false;
	}

	//移除键值
	void erase(DWORD dwKey)
	{
		if (!m_root) return;

		Node *node = m_root;
		int index;
		do
		{
			index = dwKey % 10;
			node = node->childs[index];
			dwKey /= 10;
		} while (dwKey > 0 && node);

		if (node)
		{
			m_size--;
			node->isLeaf = false;
			node->Val = NULL;

			Node *parent;
			do
			{
				if (m_root == node)
					break;

				parent = node->parent;
				if (!hasChild(node))
				{
					if (node->parent)
					{
						for (int i = 0; i < 10; i++)
						{
							if (node->parent->childs[i] == node)
							{
								node->parent->childs[i] = NULL;
								break;
							}
						}
					}

					delete node;
				}
				else
				{
					break;
				}
			
				node = parent;
			} while (node);
		}
	}

	size_t size()
	{
		return m_size;
	}

	bool empty()
	{
		return (m_size == 0);
	}

	void clear()
	{
		if (!m_root) return;
		for (int i = 0; i < 10; i++)
		{
			if (m_root->childs[i])
			{
				removeChild(m_root->childs[i]);
				m_root->childs[i] = NULL;
			}
		}

		m_size = 0;
	}

private:
	bool hasChild(Node *node)
	{
		if (!node) return false;

		for (int i = 0; i < 10; i++)
		{
			if (node->childs[i])
			{
				return true;
			}
		}
		return false;
	}

	void removeChild(Node *node)
	{
		if (!node) return;

		for (int i = 0; i < 10; i++)
		{
			if (node->childs[i])
				removeChild(node->childs[i]);
		}

		delete node;
	}

	//反序KEY
	DWORD reverseKey(DWORD dwKey)
	{
		if (dwKey == 0) return 0;
		DWORD dwValue = 0;
		do
		{
			dwValue = dwValue * 10 + dwKey % 10;
			dwKey /= 10;
		} while (dwKey > 0);

		return dwValue;
	}
};

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值