I have a problem with, i think, function INPUT. But i can't understand how to fix it
[functions code]
typedef struct Item {
int data;
struct Item* next;
} Item;
typedef struct Queue{
Item* head;
Item* tail;
} Queue;
void input(Queue* list,int* stroka) {
Item* new = (Item*)malloc(sizeof(Item));
new->data = *stroka;
new->next = NULL;
if (!list->head) {
list->head = new;
list->tail = new;
} else {
list->tail->next = new;
list->tail = new;
}
}
int main() {
int stroka;
Queue* list = (Queue*)malloc(sizeof(Queue));
while(stroka != EOF) {
stroka = getchar();
input(list, &stroka);
}
printf("\n");
print(list);
}
[valgrind message]
Conditional jump or move depends on uninitialised value(s)
==29969== at 0x10931A: input ()
==29969== by 0x1093CF: main ()
==29969== Uninitialised value was created by a heap allocation
==29969== at 0x48427B5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==29969== by 0x1093B1: main ()
tried to change some blocks of code but i didn't come to anything
In the while loop you are using an uninitialized object of the type int and trying it to compare with a null pointer
int stroka;
Queue* list = (Queue*)malloc(sizeof(Queue));
while(stroka != EOF) {
stroka = getchar();
input(list, &stroka);
}
that does not make sense.
And there is no need to allocate dynamically an object of the type Queue.
Also instead of getchar it is much better to use scanf to enter integers instead of single characters that will be interpreted as integers including the new line character '\n'..
Also there is no any sense to pass the object stroke through a pointer to the function.
The function should be declared and defined the following way
int input( Queue* list, int data )
{
Item *new_item = malloc( sizeof( *new_item ) );
int success = new_item != NULL;
if ( success )
{
new_item->data = data;
new_item->next = NULL;
if ( list->head == NULL )
{
list->head = new_item;
}
else
{
list->tail->next = new_item;
}
list->tail = new_item;
}
return success;
}
And in main you can write for example
int main( void )
{
Queue list = { .head = NULL, .tail = NULL };
for ( int data; scanf( "%d", &data ) == 1; )
{
input( &list, data );
}
printf("\n");
print(list);
}
If you want to enter characters then declare the function like
int input( Queue* list, char data );
and in main write
for ( char data; scanf( " %c", &data ) == 1; )
{
input( &list, data );
}
Pay attention to the space in the format string in the call of scanf. It allows to skip white space characters.
And do not forget to write a function that will free all the allocated memory when the list will nit be required any more.
Related
I'd like to add an element to a list of element. My list is a struct containing a double, an integer and a pointer to the next element. Could someone tell me how to do the Add function please
#include <stdio.h>
#include <stdlib.h>
typedef struct Liste Liste;
struct Liste{
double c;
int n;
Liste* next; // pointe sur l'élément suivant
};
void Add(Liste array, Liste item) {
Liste* last = array.next;
while (last != NULL) {
last = last->next;
}
array.next = &item;
printf("%p\n", array.next);
}
int main(){
Liste array = {12.4, 4, NULL};
printf("%f\n", array.c);
Liste item = {15.4, 7, NULL};
Add(array, item);
printf("%p\n", array.next);
return 0;
}
Pass-by-value
In Add, C makes a copy of all the function parameters; their scope is the function itself. When one returns, the function parameters are popped from the stack and there is no way to get them back, as you have seen. The way to mutate structures is to pass a pointer to the structure, then modify that pointer using the structure pointer dereference operator, (arrow ->.)
Design
The reason one would use a linked-list is it is very cheap to reorder it, but the head of your linked-list is fixed, so you can't change it. You might change this by delineating the container, the list itself, from the contents. This is similar to using a double-pointer, but I think less confusing.
struct Noeud {
double c;
int n;
struct Noeud* next; // pointe sur l'élément suivant
};
struct Liste {
struct Noeud *tete; // singly-linked-list est defini par un pointer seul
};
Then you can add, (I've included assert.h.)
/* `O(n)` */
static void AddQueue(struct Liste *liste, struct Noeud *item) {
assert(liste && item && item->next == NULL);
struct Noeud* last = liste->tete;
if(last == NULL) { // case spécieux
liste->tete = item;
} else {
while (last->next != NULL) {
last = last->next;
}
last->next = item;
}
}
However, it's much simpler and asymptotically faster to add at the beginning of the list.
Pointerstructures like a linked list are powerful tools with a wide rage of application.
But first you have to understand pointers.
A pointer is a datastructure which contains the address of a datastructure.
Whenever you call a function the arguments of it are copied (pushed) to the stack.
If the arguments require a lot of storage space you use a pointer instead.
the code below uses pointers to create a linked list
#include "stdio.h"
#include "stdlib.h"
#include "stdbool.h"
typedef struct List List;
struct List{
double c;
int n;
List *next;
};
void AddItemEnd( List *RootItem, List *Item )
{
List *Last = RootItem;
while( Last->next != NULL )
{
Last = Last->next;
}
Last->next = Item;
}
void AddItemAtPos( List *RootItem, List *Item, unsigned int Pos )
{
if( Pos == 0 )
{
Item->next = RootItem;
}
else
{
List *TempItem = RootItem;
for( unsigned int i = 1; i < Pos && TempItem->next != NULL; ++i )
{
TempItem = TempItem->next;
}
Item->next = TempItem->next;
TempItem->next = Item;
}
}
void RemoveItemAtPos( List *RootItem, unsigned int Pos )
{
if( Pos == 0 )
{
free( (void*) RootItem );
}
else
{
List *TempItem = RootItem;
for( unsigned int i = 1; i < Pos && TempItem->next != NULL; ++i )
{
TempItem = TempItem->next;
}
if( TempItem->next == NULL )
{
return;
}else if( TempItem->next->next != NULL )
{
List *ItemToDelete = TempItem->next;
TempItem->next = TempItem->next->next;
free( (void*) ItemToDelete );
}else
{
free( (void*) TempItem->next );
TempItem->next =NULL;
}
}
}
int main(void) {
List *RootItem = malloc( sizeof( List ));
RootItem->c = 12.4;
RootItem->n = 4;
RootItem->next = NULL;
List *Item1 = malloc( sizeof(List ));
Item1->c = 15.4;
Item1->n = 7;
Item1->next = NULL ;
AddItemEnd( RootItem, Item1 );
List *IterationItem;
printf( "List created with AddItemEnd()\n\n" );
for( IterationItem = RootItem; IterationItem != NULL; IterationItem = IterationItem->next )
{
printf( "c: %lf\nn: %d\n\n", IterationItem->c, IterationItem->n );
}
List *item2 = malloc( sizeof( List ));
item2->c = 23.4;
item2->n = 1846;
item2->next = NULL ;
AddItemAtPos( RootItem, item2, 1 );
printf( "\n\nList extended with AddItemAtPos()\n\n");
for( IterationItem = RootItem; IterationItem != NULL; IterationItem = IterationItem->next )
{
printf( "c: %lf\nn: %d\n\n", IterationItem->c, IterationItem->n );
}
RemoveItemAtPos(RootItem, 1 );
printf( "\n\nList after RemoveItemAtPos()\n\n");
for( IterationItem = RootItem; IterationItem != NULL; IterationItem = IterationItem->next )
{
printf( "c: %lf\nn: %d\n\n", IterationItem->c, IterationItem->n );
}
free( (void*) RootItem );
free( (void*) item2 );
return 0;
}
The key elements when dealing with lists is pointers
and using memory allocation.
If we disregard your add function and just do a simple
example you will probably get the geist of it.
First allocate you starting list like this
Liste* array = malloc(sizeof(Liste));
Now you have one uninitialized block of memory
that array points to. You then need to initialize
it.
array->c = 12.4;
array->n = 4;
array->next = NULL;
in order to add a new entry to your list you
need to again allocate memory for the next node and
initialize it plus set the previous node next pointer
to point to it i.e. array->next.
Liste* item = malloc(sizeof(Liste));
item->c = 15.4;
item->n = 7;
item->next = NULL;
array->next = item;
now you have a list of two elements where array points
to the first
printing your short list
Liste* p = array;
while (p != NULL)
{
printf("%lf %d %p\n", p->c, p->n, p->next);
p = p->next;
}
So your Add functions does not allocate memory and copies
the parameters so that is not going to work.
Your Add function should have a pointer either to either the first or last item in your list e.g.
void Add(Liste* start, double c, int n)
Then you do as I showed you above and create a new node and assign the values
If you want to be able to pass an empty list to Add then you need to do differently, since start is copied it cannot be changed, you need to pass the address of the pointer
void Add(List** start, double c, int n)
{
Liste* node = malloc(sizeof(Liste));
...
(* put node in the list *)
if (*start == NULL)
{
*start = node; // first
}
else
{
(* find last node, see print loop *)
(* once you have last item, set it to point to node)
}
...
}
int main()
{
Liste* start = NULL;
Add(&start, 12.4, 4);
Add(&start, 15.4, 7);
...
typedef struct LinkedList LinkedList;
struct LinkedList {
LinkedList* next;
char* head;
char current;
};
LinkedList makeList()
{
char* headPointer = calloc(60, sizeof(char));
LinkedList temp = { 0xCCCCCCCC, headPointer, 0 };
return temp;
}
int addToList(LinkedList* lstPointer, char toAdd) {
if (lstPointer->head == NULL || lstPointer->head == 0xCCCCCCCC)
return -1;
if (lstPointer->current + 1 < 60) { /* enough space in the list to add */
*(lstPointer-> head + lstPointer -> current) = toAdd;
lstPointer->current = lstPointer->current + 1;
}
else /* not enough space, will create new node in the list */
{
if (lstPointer->next == 0xCCCCCCCC) {
LinkedList nextNode = makeList();
lstPointer->next = &nextNode;
}
return addToList(lstPointer->next, toAdd);
}
/*Added succsessfully*/
return 0;
}
int main(){
char chr;
LinkedList lst = makeList();
while ((chr = getchar()) != EOF) {
if (addToList(&lst, chr) == -1)
return -1;
}
return 0;
}
i am trying to use linked list but after i fill the first, i create a new one and able to add an item to it. on the second item the next list pointer get destroyed by getchar(). i have no idea why or how is it related.
In makelist you need to allocate a new list, but then instead of returning it, you copy it into a local variable, leaking the memory that you just allocated. Instead, return a pointer:
LinkedList *makeList() // Note *
{
LinkedList *temp = calloc(1, sizeof(LinkedList));
temp->head = calloc(60, sizeof(char));
temp->next = 0;
temp->current = toAdd;
return temp; // Note temp is a pointer
}
In addToList you don't need the nextNode variable:
lstPointer->next = makelist();
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node *tree_ptr;
typedef struct table * Table;
struct node
{
char* element;
tree_ptr left, right;
};
typedef struct table
{
tree_ptr head;
int tree_h;
}table;
char* key = NULL;
Table insert(char* insert_key,Table t)
{
int height = 0;
//tree_ptr ptr = t->head;
tree_ptr *ptr = &(t->head);
key = strdup(insert_key);
tree_ptr new_node = malloc(sizeof(struct node));
new_node->element = key;
new_node->left = NULL;
new_node->right = NULL;
if ( t->head==NULL ){
*ptr = new_node;
t->tree_h = 0;
printf("head:%s\n",t->head->element);
return t;
}
while(1){
if ( strcmp(insert_key, (*ptr)->element)<0 ){
if ( (*ptr)->left ==NULL ){
(*ptr)->left = new_node;
height++;
if ( height > t->tree_h)
t->tree_h = height;
break;
}
else{
(*ptr) = (*ptr)->left;
height++;
}
}
else if ( strcmp(insert_key, (*ptr)->element)>0 ){
if ( (*ptr)->right ==NULL ){
(*ptr)->right = new_node;
height++;
if ( height > t->tree_h)
t->tree_h = height;
break;
}
else{
(*ptr) = (*ptr)->right;
height++;
}
}
else break;
}
return t;
}
int main() {
Table t = malloc(sizeof(table));
t->head = NULL;
t = insert("one", t);
t = insert("two", t);
t = insert("three", t);
printf("%s\n",t->head->element);
return 0;
}
The above is a simplified program, some definition code is given, so I could not change the basic structure, like table, Table, node, tree_ptr, while others could be changed.
What I am trying to implement is a spellchecking, the table stored the head of the tree and some other properties of the tree(which is omitted here), the tree is implemented as an ordered binary tree.
I find that, insert() works well up to two times, after the (*ptr) = (*ptr)->right; the t->head is changed as well. So after using it two times, I lost the head of the tree.
How to modify my insert()?
To insert a node into a tree you first have to search for an empty leaf. Apart from this you do not modify t, so there is no need of writing it back by return value:
void insert( char* insert_key, Table t )
{
// serach empty leaf, where to insert the new node
tree_ptr *ptr = &(t->head); // start at head
while ( *ptr != NULL ) // end if empty leaf is found
{
int cmpRes = strcmp( insert_key, (*ptr)->element );
if ( cmpRes == 0 )
return; // insert_key already is member of tree
if ( cmpRes < 0 )
ptr = &((*ptr)->left); // step down to left child
else
ptr = &((*ptr)->right); // step down to right child
}
// create new node
tree_ptr new_node = malloc( sizeof(struct node) );
new_node->element = strdup( insert_key );
new_node->left = NULL;
new_node->right = NULL;
// place new node at empty leaf
*ptr = new_node;
}
With this recursive function you can print your tree:
void printTree( tree_ptr ptr )
{
if ( ptr == NULL )
return;
printTree( ptr->left );
printf( "%s\n", ptr->element );
printTree( ptr->right );
}
printTree( t->head );
And with this one you can free all nodes of your tree:
void deleteTree( tree_ptr ptr )
{
if ( ptr == NULL )
return;
deleteTree( ptr->left );
deleteTree( ptr->right );
free( ptr );
}
deleteTree( t->head );
t->head = NULL;
The problem is ptr is pointing to the address of the pointer to a struct node, instead of directly pointing to a struct node:
tree_ptr *ptr = &(t->head);
Then when iterating in the while loop, you aren't changing the pointer ptr, but the pointer it is pointing to, which is t->head:
(*ptr) = (*ptr)->left;
This overwrites the pointer, t->head on every iteration, effectively erasing the nodes that pointer pointed to, and leaking memory.
Instead use a normal pointer to the struct node:
struct node* iter = t->head;
...
if ( strcmp(insert_key, iter->element)<0 ){
...
}
else{
iter = iter->left;
....
And I would highly suggest removing those typedefs that hide the pointer, because they make the code hard to read and obfuscate the types, which is not desirable in this context:
typedef struct node *tree_ptr;
typedef struct table * Table;
Also note that if the loop finds a duplicate, the allocated node is not freed, leaking the memory.
code print elements after store them :
void print(struct node* root)
{
while ( c != NULL )
{
printf( "\n%d ", c->line1);
printf( "%s", c->curr );
c = c->next;
}
}
print method
Just looking at the code, this line seems like a potential issue:
temp->curr=current_input;
It looks like all the nodes .curr will get set = current_input. I'm guessing you need to do something like:
temp->curr = malloc(1 + strlen(current_input));
strcpy(tmp->curr, current_input);
Use strcpy_s if strcpy causes a warning.
First you should realize a list consists of nodes, which contain pieces of your data — so you need to allocate a new node for each piece of data you want to store in a list.
Then you insert each newly created node into the list and finally print the list when done.
Additionaly remember that data need to be either copied into the node (like line1) or copied somewhere else, for example onto the heap, and then linked to the node with a pointer, like curr (see the answer by #rcgldr).
struct node *root = NULL;
struct node *createnode(int line, const char *input)
{
struct node *n = malloc(sizeof(struct node));
if(n != NULL)
{
n->line1 = line;
n->curr = input;
n->next = NULL;
}
return n;
}
void insertnode(struct node* n)
{
n->next = root;
root = n;
}
void printlist(struct node* n)
{
for( ; n != NULL; n = n->next)
{
printf( "%d: %s\n", n->line1, n->curr);
}
}
int main(int argc, const char * argv[])
{
char *input;
struct node *temp;
type t;
do
{
t=getword(); //call to get the type of t
switch (t)
{
case number:
case keyword:
input = strdup(current_input); // make a copy of user input
if(input != NULL)
{
temp = createnode(line, input);
if(temp != NULL) // created?
insertnode(temp); // insert into the list
else
{
free(input); // free unused input copy
t = EOF; // make the loop terminate
}
}
else // user input copy failed
t = EOF; // make the loop terminate
break;
default:
break;
}
}
while (t != EOF);
print(root);
return 0;
}
Here's the code , i run it with one example it works , but when it comes
to comparing i do not understand what's wrong ? , thanks in advance for
any help .I need to print dictionary texts properly (inserting , printing) , can not still come up with a solution , i mean using dictionary data structure like .
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
typedef struct Node_s {
char *element;
struct Node_s *left, *right;
} Node;
typedef struct {
Node *head;
} Table;
//Table *initialize();
//Node *createNode(const char *element);
Table *initialize() {
Table *tb = malloc(sizeof(Table)*1000);
tb->head = NULL;
return tb;
}
Node *createNode( char * element ) {
Node *temp = malloc(sizeof(temp));
temp->element = element ;
temp->left = temp->right = NULL;
return temp;
}
void insert(Table *temp, char *element) {
Node *nd = createNode(element);
Table * place = NULL;
Node *new = NULL;
int cmp = 0;
if(temp->head == NULL) {
temp->head= nd;
printf("empty ! \n");
return;
}
else {
Table *current = temp;
while (current!=NULL) {
cmp = strcmp(current->head->element,element);
if(cmp < 0) {
current->head= current->head->left;
}
else if(cmp > 0) {
current->head = current->head->right;
}
} //while
place = current;
new = nd;
if(cmp > 0 ) {
place->head->right = new ;
}
else if(cmp <0 ) {
place->head->left = new;
}
}
}
void print_table(Table *temp) {
if(temp!=NULL || !temp->head) return;
print_table(temp->head->left);
printf("%s \n",temp->head->element);
print_table(temp->head->right);
}
int main () {
Node * nd = NULL;
//nd->element = "key";
// nd = createNode("key");
Table *tb = initialize();
//tb->head = createNode("key");
//tb->head = createNode("key");
insert(tb, "table element1");
insert(tb, "table element2");
insert(tb, "table element2");
//nd = createNode("key1");
// print_table(t);
//printf("%s \n",nd->element);
print_table(tb);
// printf("%s \n",tb->head->element);
free(nd);
return 0;
}
There are a lot of potential bugs here, but your primary issue is in the following line of createNode:
Node *temp = malloc(sizeof(temp));
Here you're doing a sizeof(temp) and temp is a pointer. This means that you are only allocating enough memory for a pointer (usually 8 bytes). You are hence writing outside of allocating memory when using the left/right members of the heap allocated structure. The fix:
Node *temp = malloc(sizeof(Node));
// EXTRA: I also recommend that you verify that the allocation was successful
if (temp) {
temp->element = element ;
temp->left = temp->right = NULL;
}
return temp;
In printTable, you should also verify that temp itself isn't NULL as you are passing the function parameters that might be NULL:
if(!temp || !temp->head) return;
Also, remove the free(nd); at the end of main, as calling free() on unallocated heap memory corrupts the heap and typically leads to a segfault.
Your printing method crashes when reaching the last node on the left because it will call print_table(NULL) since there's nothing more on the left. After that when it executes the line
if(!temp->head) return;
You get a memory access violation because temp is NULL, you should also check if temp itself is NULL.
if( !temp || !temp->head ) return;
That should fix your problem.
One issue right away is on your second call to insert:
while (current != NULL) {
cmp = strcmp(current->head->element, element); // this line
You didn't check if current->head is NULL itself. According to what you've implemented, you use head as a sentinel, thus it can be NULL. However, your search loop totally forgot about this condition and assumes that head is never NULL.
Your loop doesn't seem fundamentally correct. You traverse the left, so what is supposed to happen if the left branch "runs out" (as it does now when you call insert the second time)?
In addition, your insert function has a memory leak. You potentially allocate 2 new nodes here:
Node *nd = createNode(element);
and here:
new = createNode(element);
Only one is stored while the other is leaked.
Another issue is that your tree does nothing in the while loop if the two items are equal. Two equal items results in an infinite loop:
while (current!=NULL)
{
cmp = strcmp(current->head->element,element);
if(cmp < 0)
current->head= current->head->left;
else if(cmp > 0)
current->head = current->head->right;
else
printf("these are equal ! \n"); // but we don't do anything with current!
}
If the goal is to not have duplicates, then you should exit this function if a duplicate is found. If the goal is to store duplicates, only test for < 0, anything else, goes on the right branch.
This might be what you are looking for.
It handles a doubly linked list
error checking is added
removed undesirable/unnecessary typedef's from struct definitions
corrected the logic to link in new nodes
avoided recursion in the printing of the linked list
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
struct Node
{
char *element;
struct Node *left;
struct Node *right;
};
// define the head pointer for the linked list
struct Node *head = NULL;
// struct Node *createNode(const char *element);
struct Node *createNode( char * element )
{
struct Node *pNewNode = NULL;
if( NULL == (pNewNode = malloc(sizeof(struct Node)) ) )
{ // then, malloc failed
perror( "malloc for new node failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
pNewNode->element = element ; // copies a char pointer
pNewNode->left = NULL;
pNewNode->right = NULL;
return pNewNode;
} // end function: createNode
void insert(char *element)
{
int cmp = 0;
// get ptr to first node in list
struct Node *pCurrentNode = head;
// create the node to be inserted into linked list
struct Node *pNewNode = createNode(element);
if (pCurrentNode == NULL)
{ // then list empty
head = pNewNode;
printf("added first node\n");
return;
}
// implied else, not first node
while (pCurrentNode->right)
{
cmp = strcmp(pCurrentNode->element,element);
if(cmp < 0)
{
// insert new node before current node
pNewNode->right = pCurrentNode;
pNewNode->left = pCurrentNode->left;
pCurrentNode->left = pNewNode;
(pNewNode->left)->right = pNewNode;
}
else if(cmp > 0)
{
// step to next node
pCurrentNode = pCurrentNode->right;
} // end if
// note: if data same, don't insert new node
} //while
if( pCurrentNode->right == NULL )
{ // then, reached end of list
// append new node to end of list
pNewNode->left = pCurrentNode;
pNewNode->right = NULL;
pCurrentNode->right = pNewNode;
} // end if
} // end function: insert
void print_table()
{
struct Node *pCurrentNode = head;
if( pCurrentNode == NULL ) return;
// implied else, list not empty
while( pCurrentNode )
{
printf("%s \n",pCurrentNode->element);
pCurrentNode = pCurrentNode->right;
} // end while
} // end function: print_table
void cleanup()
{
struct Node *pCurrentNode = head;
while( pCurrentNode )
{
pCurrentNode = pCurrentNode->right;
free( pCurrentNode->left );
}
} // end function: cleanup
int main ()
{
// exercise the insert function
insert("table element1"); // append first element
insert("table element2"); // append second element
insert("table element4"); // append third element
insert("table element3"); // insert forth element
insert("table element3"); // duplicate within list
insert("table element4"); // duplicate at end of list
print_table();
cleanup();
return 0;
} // end function: main
I tried a different implementation, it compiles and works, it does not allow duplicates.
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#define ELEMENT_SIZE 1024
typedef struct Node_s
{
char element[ELEMENT_SIZE];
struct Node_s *left, *right;
} Node;
Node * createNode(char *element)
{
Node *node = malloc(sizeof(Node));
node->left = NULL;
node->right = NULL;
memcpy(node->element, element, ELEMENT_SIZE);
return node;
}
void free_node(Node *node)
{
if(!node)
return;
free_node(node->left);
free_node(node->right);
free(node);
}
Node * insert(Node **head_ptr, char *element)
{
Node *head = *head_ptr;
if(head == NULL){
Node *node = createNode(element);
head = node;
*head_ptr = node;
return node;
}else{
int comp = strcmp(head->element, element);
if(comp < 0){
// go left
if(head->left == NULL){
// set element to be temp left
Node *node = createNode(element);
head->left = node;
return node;
}else{
return insert(&head->left, element);
}
}else if(comp > 0){
// go right
if(head->right == NULL){
// set element to be temp left
Node *node = createNode(element);
head->right = node;
return node;
}else{
return insert(&head->right, element);
}
}else{
// element exists
printf("Element \"%s\" already exists\n", element);
return NULL;
}
}
}
void print_table(Node *temp)
{
if(!temp)
return;
printf("%s \n",temp->element);
print_table(temp->left);
print_table(temp->right);
}
int main ()
{
Node *nd = NULL;
printf("Address of nd is %p\n", &nd);
Node *n1 = insert(&nd, "table element 1");
n1 = insert(&nd, "table element 2");
n1 = insert(&nd, "table element 3");
n1 = insert(&nd, "element 1");
n1 = insert(&nd, "element 2");
n1 = insert(&nd, "element 3");
n1 = insert(&nd, "alternative 1");
n1 = insert(&nd, "alternative 2");
n1 = insert(&nd, "alternative 3");
n1 = insert(&nd, "alternative 1");
n1 = insert(&nd, "alternative 2");
n1 = insert(&nd, "alternative 3");
print_table(nd);
free_node(nd);
return 0;
}