我们将在C++和OOP中使用智能指针来实现trie。在这里,我们已经讨论了使用递归实现trie数据的方法
在我们的实现节点中,特里看起来像:
class TrieNode{
public:
// Use of shared_ptr for storing Children
// Pointers of TrieNode
shared_ptr children[ALPHABET_SIZE];
// Tracks whether If this Node is the end of
// any word stored in Trie
bool isWord;
// Constructor for TrieNode
TrieNode()
{
for(int i=0; i
接口是显示我们的对象类的功能的类,该对象类仅具有纯虚函数。在这里,概念界面将进行更详细的讨论。
// Interface representing functionalities
// of Trie Data Structure
class interface {
public:
interface() {}
virtual ~interface() {}
// Pure virtual functions showing all
// the functions of my Trie class
// To convert character to integer like hashing
virtual int i2c(char) = 0;
// Inserts word to Trie
virtual void insertWord(string&) = 0;
// Deletes word if present
virtual bool deleteWord(string&) = 0;
// To search a word in Trie
virtual bool searchWord(string&) = 0;
// Checks whether there is any children present
// for any node
virtual bool isEmptyNode(shared_ptr)
const = 0;
};
nullptrs存储NULL,这表明该位置的其他任何字符串都没有路径
下图显示了将“怪胎”插入空的特里。
下图显示了将“ geeksfor”插入到特里。怪胎p已经退出了。因此,它重叠。
下图显示了将“ trie”插入到trie中
为什么要使用shared_ptr而不是所有其他智能指针(auto_ptr,unique_ptr,weak_ptr)?
由于在构造Trie时可能会遇到这样的情况,我们可能不得不共享指向另一个临时shared_ptr的特定指针的资源以遍历Trie的事实,所以我们使用了shared_ptr 。在这一点上,shared_ptr优于上面提到的任何其他指针。
下面是上述方法的实现:
#include
// For shared_ptr class
#include
using namespace std;
#define ALPHABET_SIZE 26
// Trie Node class
class TrieNode {
public:
// Use of shared_ptr for storing Children
// Pointers of TrieNode
shared_ptr children[ALPHABET_SIZE];
// Tracks whether If this Node is the end of
// any word stored in Trie
bool isWord;
// Constructor for TrieNode
TrieNode()
{
for (int i = 0; i < ALPHABET_SIZE; i++) {
children[i] = shared_ptr();
}
isWord = false;
}
};
// Interface representing functionalities
// of Trie Data Structure
class interface {
public:
interface() {}
virtual ~interface() {}
// Pure virtual functions showing all
// the functions of my Trie class
// To convert character to integer like hashing
virtual int i2c(char) = 0;
// Inserts word to Trie
virtual void insertWord(string&) = 0;
// Deletes word if present
virtual bool deleteWord(string&) = 0;
// To search a word in Trie
virtual bool searchWord(string&) = 0;
// Checks whether there is any children present
// for any node
virtual bool isEmptyNode(shared_ptr)
const = 0;
};
class Trie : public interface {
// Storing root of the Trie
shared_ptr root;
int Total_words;
public:
Trie()
{
root = shared_ptr
(new TrieNode());
Total_words = 0;
}
~Trie()
{
// Need not delete anything
// as shared_ptr deallocates
// all memory automatically
}
// To convert characters of string into
// integer like hashing of character
int i2c(char c)
{
return static_cast(c - 'a');
}
// Insert word function
void insertWord(string& trieString)
{
shared_ptr current = root;
for (int i = 0; i < trieString.size(); i++)
{
// If word after some prefix is not
// present then creates new node
if (current->children[i2c(trieString[i])] ==
shared_ptr(nullptr))
{
current->children[i2c(trieString[i])] =
shared_ptr(new TrieNode());
}
current = (current->children[i2c(trieString[i])]);
}
// Now word is added in Trie so at leaf node
// for that word isWord=true
current->isWord = true;
}
// Searching for word whether it is
// present in Trie
bool searchWord(string& trieString)
{
shared_ptr current = root;
for (int i = 0; i < trieString.size(); i++)
{
// If at any point in Trie Node for particular
// character is not present means nullptr then
// return false
if (current->children[i2c(trieString[i])] ==
shared_ptr(nullptr))
return false;
current = current->children[i2c(trieString[i])];
}
// At the end of the word checking whether this
// word is really present or not
if (current->isWord == true)
return true;
return false;
}
bool Partdelete(string& trieString, shared_ptr&
checkout)
{
// Word is not present in the Trie then returns
// false and stops further recursion
if (checkout == nullptr)
return false;
// At the end of the word if the word is
// present in trie then setting isWord to
// false either returing false
if (trieString.size() == 0) {
if (checkout->isWord == true) {
checkout->isWord = false;
return true;
}
return false;
}
// String excluding first character
string part = trieString.substr(1);
// Recusive call to Partdelete for
// rest of the string(part)
if (Partdelete(part, checkout->
children[i2c(trieString[0])])) {
// Checks whether it is empty node
// then delete this node
if (isEmptyNode(checkout->
children[i2c(trieString[0])])) {
// Resetting memory and making it nullptr
checkout->children[i2c(trieString[0])].
reset();
checkout->children[i2c(trieString[0])] =
nullptr;
return true;
}
else
return true;
}
else
return false;
return false;
}
// For ease of recursion; passing
// root to Partdelete
bool deleteWord(string& trieString)
{
if (Partdelete(trieString, root))
return true;
return false;
}
// Checks whether there is no children present
bool isEmptyNode(shared_ptr check) const
{
for (int i = 0; i < ALPHABET_SIZE; i++) {
if (check->children[i] != nullptr ||
check->isWord == true)
return false;
}
return true;
}
};
// Driver code
int main()
{
// Again using shared_ptr to store Trie
// you can use auto_ptr here
shared_ptr myTrie(new Trie());
string word1 = "geeksfor";
string word2 = "geeksforgeeks";
string word3 = "nothing";
myTrie->insertWord(word1);
if (myTrie->searchWord(word1))
cout << word1 << ": Is Present" << endl;
else
cout << word1 << ": Not Present" << endl;
if (myTrie->searchWord(word3))
cout << word3 << ": Is Present" << endl;
else
cout << word3 << ": Not Present" << endl;
myTrie->insertWord(word2);
if (myTrie->deleteWord(word2))
cout << word2 << ": Successfully deleted" << endl;
else
cout << word2 << ": Not Present" << endl;
if (myTrie->searchWord(word2))
cout << word2 << ": Is Present" << endl;
else
cout << word2 << ": Not Present" << endl;
}
输出:
geeksfor: Is Present
nothing: Not Present
geeksforgeeks: Successfully deleted
geeksforgeeks: Not Present