I have been trying to implement the basic functions of inserting characters into a trie data structure in C. I have been trying to figure out what I am doing wrong, but for the last day or so I've been stumped/stuck.
Heres some code I've written up:
TR head = NULL;
void initDict () {
head = NULL;
}
TR newNode (char item) {
TR temp;
temp = malloc (sizeof(*temp));
temp->thisChar = item;
temp->child = NULL;
temp->sibling = NULL;
return temp;
}
TR insertInOrder (char item, TR trie) {
if (trie == NU开发者_JAVA技巧LL) {
trie = newNode(item);
} else if (trie->thisChar < item) {
insertInOrder(item, trie->sibling);
} else if (trie->thisChar > item) {
char temp = trie->thisChar;
trie->thisChar = item;
insertInOrder(temp, trie->sibling);
}
return trie;
}
void insert (char *word) {
char letter = *word;
TR temp = NULL;
while (*word != '\0') {
letter = *word;
if (head == NULL) {
head = newNode(letter);
temp = head->child;
word++;
} else {
temp = insertInOrder(letter, temp);
temp->child = head->child;
head->child = temp;
word++;
}
}
}
I can't figure this out...
P.S checkLetter, is a boolean function that checks if the letter is already inside the trie (through traversing through the trie structure, i.e. trie = trie->sibling)
Any help would be appreciated =]
Cheers!
EDIT: changed my code, so that insertInOrder returns a value, but since insert is a void function and has to stay a void function, I don't know of a way to insert nodes further down into the head of the trie (i.e. head->child, head->child->child etc)
You could re-think your insertion algorithm :-)
I am not very good teacher, so I'll just give you the solution without any good motivations. This is not compiled and verified though, think of this as pseudo-code to give you an idea of what I think is a better algorithm that handles some corner cases you seem to have missed, plus uses the 'head' pointer differently to yield a more consistent algorithm:
// 'head' is assumed to be a valid pointer, its 'child' field either NULL or a valid
// pointer
TR currentNode = head;
while ( *word )
{
assert(currentNode != NULL);
if ( currentNode->child == NULL || currentNode->child->thisChar < *word )
{
// We need to insert a new node first in the child list
TR newNode = malloc(sizeof *currentNode);
newNode->thisChar = *word;
newNode->sibling = currentNode->child;
newNode->child = NULL;
currentNode->child = newNode;
currentNode = newNode;
}
else
{
// Find the place to insert next node
currentNode = currentNode->child;
while ( currentNode->sibling && currentNode->thisChar < *word )
currentNode = currentNode->sibling;
// If the current node already represents current character, we're done
// Otherwise, insert a new node between the current node and its sibling
if ( currentNode->thisChar != *word )
{
TR newNode = malloc(sizeof *currentNode);
newNode->thisChar = *word;
newNode->child = NULL;
newNode->sibling = currentNode->sibling;
currentNode->sibling = newNode;
currentNode = newNode;
}
}
word++;
}
At the start of your insertInOrder function, you check if you need to allocate a new node. Then you allocate a new node if needed, but you store the address of the new node in a local that goes away as soon as you return.
Feels like maybe the insertInOrder function should return a TR that insert does something good with?
精彩评论