Trie 字典树 删除操作

字典树的删除操作:

1 没找到直接返回

2 找到叶子节点的时候,叶子节点的count标志清零,代表不是叶子节点了

3 如果当前节点没有其他孩子节点的时候,可以删除这个节点

判断是否需是叶子节点,就检查叶子节点的count标志就可以了。

判断是否有其他孩子节点就需要循环26个节点了,如果都为空,那么就没有其他孩子节点了。

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <string>

class TrieDelete_2
{
	static const int ARRAY_SIZE = 26;
	struct Node
	{
		int val;
		Node *children[ARRAY_SIZE];
		explicit Node(int k = 0) : val(k)
		{
			for (int i = 0; i < ARRAY_SIZE; i++)
			{
				children[i] = NULL;
			}
		}
		~Node()
		{
			for (int i = 0; i < ARRAY_SIZE; i++)
			{
				if (children[i]) delete children[i];
				children[i] = NULL;
			}
		}
	};

	struct Trie
	{
		Node *emRoot;
		int count;
		explicit Trie(int c = 0) : count(c)
		{
			emRoot = new Node;//emRoot(NULL) {},应该分配emRot空间比较合理
		}
		~Trie()
		{
			if (emRoot) delete emRoot;
			emRoot = NULL;
		}
	};

	void insert(Trie *trie, char keys[])
	{
		int len = strlen(keys);

		Node *pCrawl = trie->emRoot;
		trie->count++;

		for (int i = 0; i < len; i++)
		{
			int k = keys[i] - 'a';
			if (!pCrawl->children[k])
			{
				pCrawl->children[k] = new Node;
			}
			pCrawl = pCrawl->children[k];
		}
		pCrawl->val = trie->count;
	}

	bool search(Trie *trie, char key[])
	{
		int len = strlen(key);
		Node *pCrawl = trie->emRoot;
		for (int i = 0; i < len; i++)
		{
			int k = key[i] - 'a';
			if (!pCrawl->children[k])
			{
				return false;
			}
			pCrawl = pCrawl->children[k];
		}
		return pCrawl->val != 0;
	}

	bool isFreeNode(Node *n)
	{
		for (int i = 0; i < ARRAY_SIZE; i++)
		{
			if (n->children[i]) return false;
		}
		return true;
	}

	bool isLeaf(Node *n)
	{
		return n->val != 0;
	}

	bool deleteHelp(Node *n, char key[], int lv, int len)
	{
		if (n)
		{
			if (lv == len)
			{
				if (isLeaf(n))
				{
					n->val = 0;
					if (isFreeNode(n))
					{
						delete n, n = NULL;
						return true;
					}
					return false;
				}
			}
			else
			{
				int k = key[lv] - 'a';
				if(deleteHelp(n->children[k], key, lv+1, len))
				{
					if (!isLeaf(n) && isFreeNode(n))
					{
						delete n, n = NULL;
						return true;
					}
					return false;
				}
			}
		}
		return false;
	}

	void deleteKey(Trie *trie, char key[])
	{
		int len = strlen(key);
		if (len > 0)
		{
			deleteHelp(trie->emRoot, key, 0, len);
		}
	}

public:
	TrieDelete_2()
	{
		char keys[][8] = {"she", "sells", "sea", "shore", "the", "by", "sheer"};
		Trie *trie = new Trie; 

		for(int i = 0; i < ARRAY_SIZE(keys); i++)
		{
			insert(trie, keys[i]);
		}

		deleteKey(trie, keys[0]);

		printf("%s %s\n", "she", search(trie, "she") ? "Present in trie" : "Not present in trie");

		delete trie;
	}
};

Trie 字典树 删除操作,布布扣,bubuko.com

时间: 2024-10-07 17:11:21

Trie 字典树 删除操作的相关文章

LeetCode 208.实现Trie(字典树) - JavaScript

??Blog :<LeetCode 208.实现Trie(字典树) - JavaScript> 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. Trie trie = new Trie(); trie.insert("apple"); trie.search("apple"); // 返回 true trie.search("app"); // 返回 false trie.

Phone List(简单的字典树插入操作)

Phone List Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11655    Accepted Submission(s): 3970 Problem Description Given a list of phone numbers, determine if it is consistent in the sense th

萌新笔记——C++里创建 Trie字典树(中文词典)(插入、查找、遍历、导入、导出)(上)

写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示一串可能要搜索的东西. 首先放上最终的结果: input: 1 编程入门 2 编程软件 3 编程学习 4 编程学习网站 output: 1 char : 件 2 word : 编程软件 3 char : 习 4 word : 编程学习 5 char : 网 6 word : 编程学习网 7 char : 门 8 word : 编程入门 其实这里不应

算法导论:Trie字典树

1. 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. Trie一词来自retrieve,发音为/tri:/ “tree”,也有人读为/tra?/ “try”. Trie树可以利用字符串的公共前缀来节约存储空间.如下图所示,该trie树用10个节点保存了6个字符串pool.prize.preview.prepare.produce.progress 在该trie树中,字符串preview,prepa

DFA和trie字典树实现敏感词过滤(python和c语言)

现在做的项目都是用python开发,需要用做关键词检查,过滤关键词,之前用c语言做过这样的事情,用字典树,蛮高效的,内存小,检查快. 到了python上,第一想法是在pip上找一个基于c语言的python字典树模块,可惜没找到合适的,如果我会用c写python模块的话,我就自己写一个了,可惜我还不具备这个能力, 只能用python写了,性能差一点就差点吧,内存多一点也无所谓了. 用搜索引擎看CSDN上的网友的用python实现的DFA,再参照自己以前用c语言写过的字典树,有些不大对,就自己写了一

Trie字典树 动态内存

Trie字典树 1 #include "stdio.h" 2 #include "iostream" 3 #include "malloc.h" 4 #include "string.h" 5 6 using namespace std; 7 8 #define MAX_SIZE 26 9 10 typedef struct Trie{ 11 char val; 12 bool isword; 13 struct Trie*

trie/字典树几题

以后有好多次看到这地方就过去了, 未亲自实践过. 不过今晚看了一下,感觉trie的思想还算是比较基础的. 感觉这一个链接讲的不错:http://www.cnblogs.com/BeyondAnyTime/archive/2012/07/16/2592838.html 顺便水了几道题. 具体列表可见:http://vjudge.net/contest/view.action?cid=47036#overview A:水题啦. 稍微理解下trie就能写出来了. 附个自己写的代码,还是用LRJ书上的非

【oiClass1502】查单词(Trie字典树)

题目描述 全国英语四级考试就这样如期来了,可是小y依然没有做好充分准备.为了能够大学毕业,可怜的小y决定作弊.小y费尽心机,在考试的时候夹带了一本字典进考场,但是现在的问题是,考试的时候可能有很多的单词要查,小y能不能来得及呢? 输入 第一行一个整数N,表示字典中一共有多少个单词(N<=10000).接下来每两行表示一个单词,其中:第一行是一个长度<=100的字符串,表示这个单词,全部小写字母,单词不会重复.第二行是一个整数,表示这个单词在字典中的页码.接下来是一个整数M,表示要查的单词数(M

Trie 字典树

1.UVa 1401 Remember the Word 题意:给出n个字符串集合,问其有多少种组合方式形成目标字符串. 思路:对n个字符串集合建立Trie树,保存每个结点的字符串的顺序编号.然后对这棵树查找目标字符串每一个后缀的前缀字符串,累加. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<vector>