I'm new to C programming and this is my first time working on a complicated program. The program will put a phonebook (name and number) in a binary search tree. The question that arises is why I get an error with the Recursion and all pointers that I used in the program.
My struct def is also probably wrong..
Would be happy if anyone could point me to the problem and how to solve it.
typedef struct _bstree {
char * name[60];
unsigned long phone;
struct bstree *left;
struct bstree *right;
}bstree;
typedef struct _bst_node {
int value;
struct node* next;
}bst_node;
and here are the functions (I'm not allowed to change the type of the functions or their arguments):
void bst_insert_node(bstree* bst, unsigned long phone, char *name) {
if (bst == NULL) {
bstree *newNode = (bstree *)malloc(sizeof(bstree));
newNode->phone = phone;
strcpy(newNode->name,name);
newNode->left = NULL;
newNode->right = NULL;
}
else if (bst->phone>phone) {
bst_insert_node(bst->left,phone, name); //ERROR
}
else {
bst_insert_node(bst->right, phone, name); //ERROR
}
}
bst_node* find_node(bstree* bst, unsigned long phone) {
if (bst==NULL) {
printf("Cannot find Number");
return NULL;
}
//if phone ist root
if (phone== bst->phone)
return bst; //ERROR
bstree* searching = NULL;
//left search
searching = find_node(bst->left,phone); //ERROR
if (searching)
return searching; //ERROR
// right search
searching = find_node(bst->right,phone); //ERROR
if (searching)
return searching; //ERROR
if (searching)
return searching; //ERROR
return NULL;
}
typedef struct _bstree {
char * name[60];
unsigned long phone;
struct bstree *left;
struct bstree *right;
}bstree;
Why does your tree structure have left and right.The nodes of the tree should have left and right and not the tree itself.The tree structure should just have a root node.
typedef struct _bst_node {
char name[60];
unsigned long phone;
struct _bst_node *left;
struct _bst_node *right;
}bst_node;
and then the tree structure
typedef struct _bstree {
bst_node *root; //this will point to the root node of the tree and will be NULL if the tree is emty.
}bstree;
Your insert() function should take bstree as input and insert a new bst_node in the tree.Remeber your root is bsttree::root and not bsttree itself.
void bst_insert_node(bstree* bst, unsigned long phone, char *name)
{
//insert new node
}
try this code buddy
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _bst_node
{
char name[60];
unsigned long phone;
} bst_node;
typedef struct _bstree
{
bst_node key;
struct _bstree * left;
struct _bstree * right;
} bstree;
static inline bstree * create_node(unsigned long phone, char * name)
{
bstree * newNode = (bstree *) malloc(sizeof(bstree));
newNode->key.phone = phone;
strcpy(newNode->key.name, name);
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
void bst_insert_node(bstree * bst, unsigned long phone, char * name)
{
if (bst == NULL)
{
return;
}
if (bst->key.phone > phone)
{
if (bst->left == NULL)
{
bst->left = create_node(phone, name);
return;
}
bst_insert_node(bst->left, phone, name);
}
else
{
if (bst->right == NULL)
{
bst->right = create_node(phone, name);
return;
}
bst_insert_node(bst->right, phone, name);
}
}
bst_node * find_node(bstree* bst, unsigned long phone)
{
if (bst == NULL)
{
return NULL;
}
if(bst->key.phone > phone)
{
return find_node(bst->left, phone);
}
else if (bst->key.phone < phone)
{
return find_node(bst->right, phone);
}
return &(bst->key);
}
void print_tree(bstree * bst, int level)
{
int temp = 0;
while(temp < level)
{
printf("-");
++temp;
}
printf(" (%ld-%s)\n", bst->key.phone, bst->key.name);
if (bst->left != NULL)
{
print_tree(bst->left, level + 1);
}
if (bst->right != NULL)
{
print_tree(bst->right, level + 1);
}
}
Related
We are given the main function and structures, asked to create two different linked lists. One being in ascending order and another in descending order and then joined together without changing their order. To give an example,if we have L1: 1->3->4->6 and L2: 9->8->5->2, The final list would be 1->9->3->8->4->5->6->2. This below is my work. I'm having some problems.
This is the main function:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "function.h"
struct nodeFB *startFB = NULL;
struct nodeGS *startGS = NULL;
struct newNodeFB *startNewFB = NULL;
int main()
{
int id, age;
scanf("%d", &id);
while(id!=-1)
{
scanf("%d", &age);
insertFB(&startFB, id, age);
scanf("%d", &id);
}
scanf("%d", &id);
while(id!=-1)
{
insertGS(&startGS, id);
scanf("%d", &id);
}
printFB(startFB);
printGS(startGS);
createFinalList(&startNewFB,startFB,startGS);
printAll(startNewFB);
return 0;
}
These are the given structures and the functions I've written:
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
struct nodeFB
{
int id;
int age;
struct nodeFB *next;
};
struct nodeGS
{
int id;
struct nodeGS *next;
};
struct newNodeFB
{
int id;
int age;
struct newNodeGS *next;
};
struct newNodeGS
{
int id;
struct newNodeFB *next;
};
struct nodeFB *startFB;
struct nodeGS *startGS;
//functions
struct nodeFB *insertFB( struct nodeFB **startFB, int id, int age)
{//address of the first node in the linked list of FB
struct nodeFB *newnode, *ptr;
newnode = (struct nodeFB*)malloc(sizeof(struct nodeFB));
newnode->id = id;
newnode->age = age;
if (startFB == NULL) {
newnode->next = NULL;
*startFB = newnode;
}
else {
ptr = *startFB;
while(ptr->next!=NULL) {
ptr=ptr->next;
ptr->next= newnode;
newnode->next = NULL;
}
}
return *startFB;
}
void swap(struct nodeFB *a, struct nodeFB *b) {//function to swap two nodes
int temp = a->id;
a->id = b->id;
b->id = temp;
}
void sortFB(struct nodeFB *startFB) { //function to bubble sort the given linked list
int i;
int swapped;
struct nodeFB *ptr1;
struct nodeFB *ptr2= NULL;
if (startFB==NULL) { //checking for empty list
return; }
do {
swapped = 0;
ptr1=startFB;
while (ptr1->next !=ptr2) {
if (ptr1->id > ptr1->next->id) {
swap (ptr1, ptr1->next);
swapped = 1;
}
ptr1= ptr2->next;
}
ptr2=ptr1;
}
while (swapped);
}
void printFB(struct nodeFB *startFB) { //function to display the sorted list
struct nodeFB *ptr;
ptr = startFB;
sortFB(ptr);
while(ptr != NULL) {
printf("%d %d/n", ptr->id, ptr->age);
ptr=ptr->next;
}
}
struct nodeGS *insertGS(struct nodeGS **startGS, int id ) {
struct nodeGS *newnode, *ptr;
newnode = (struct nodeGS*)malloc(sizeof(struct nodeGS));
newnode->id = id;
if (startGS == NULL) {
newnode->next = NULL;
*startGS = newnode;
}
else {
ptr = *startGS;
while(ptr->next!=NULL) {
ptr=ptr->next;
ptr->next= newnode;
newnode->next = NULL;
}
}
return *startGS;
}
void swapGS(struct nodeGS *c, struct nodeGS *d) {//function to swap two nodes
int temp = c->id;
c->id = d->id;
d->id = temp;
}
void sortGS(struct nodeGS *startGS) { //function to bubble sort the given linked list
int i;
int swapped;
struct nodeGS *ptr1;
struct nodeGS *ptr2= NULL;
if (startGS==NULL) { //checking for empty list
return; }
do {
swapped = 0;
ptr1=startGS;
while (ptr1->next !=ptr2) {
if (ptr1->id < ptr1->next->id) {
swapGS (ptr1, ptr1->next);
swapped = 1;
}
ptr1= ptr2->next;
}
ptr2=ptr1;
}
while (swapped);
}
void printGS(struct nodeGS *startGS) {
struct nodeGS *ptr;
ptr = startGS;
sortGS(startGS);
while(ptr != NULL) {
printf("%d/n", ptr->id);
ptr = ptr->next;
}
}
**struct newNodeFB *createFinalList(struct newNodeFB **startNewFB, struct nodeFB *startFB, struct nodeGS *startGS ) {
struct newNodeFB *temp1, *ptr1;
temp1=(struct newNodeFB*) malloc(sizeof(struct newNodeFB));
temp1->id= startFB->id;
temp1->age=startFB->age;
struct newNodeGS *temp2;
temp2->id= startGS->id;
struct newNodeFB *temp3 = NULL;
struct newNodeGS *temp4 = NULL;
while (temp1 != NULL && temp2 != NULL)
{
ptr1=temp1;
while (ptr1->next!=NULL) {
ptr1=ptr1->next;
ptr1->next= temp2;
temp2->next=NULL;
}
temp3=temp1->next;
temp4= temp2->next;
temp1->next=temp2;
temp2->next=temp3;
temp1=temp3;
temp2=temp4;
}
startGS = temp2;
return startNewFB;
}**
void printALL(struct newNodeFB *startNewFB){
struct newNodeFB *ptr;
ptr= startNewFB;
while(ptr != NULL) {
printf("%d %d/n%d", startNewFB->id, startNewFB->age, startNewFB->id);
ptr=ptr->next;
}
}
The simplest way to create a merged list where the nodes alternate, is to simply iterate over both lists simultaneously and add each node from the two lists into a brand new list.
Because you want to alternate between the two lists, you need to use a single loop to iterate the lists, adding one node from the first list to the new merge-list, then adding one node from the second list. Stop when both lists are finished.
In pseudoish code it could look something like this:
Node *node1 = list1->head; // Node from first list
Node *node2 = list2->head; // Node from second list
// Loop while there are nodes in at least one of the lists
while (node1 != NULL || node2 != NULL)
{
if (node1 != NULL)
{
list_add_tail(merge_list, node1->data);
node1 = node1->next;
}
if (node2 != NULL)
{
list_add_tail(merge_list, node2->data);
node2 = node2->next;
}
}
As seen it's basically the same as iterating over a single list, copying data to a new list.
Another consideration is if one is mixing struct nodeFB and struct nodeGS in one list, how could the programme tell if the node is an FB or GS? Unless the lists are of equal sizes, where they are alternating, one loses type information by mixing them together.
There are several ways to get around this. One could only allow one type of node in one list; one has to convert the types to mix the lists. One might as well convert on input and have one type of list. A more nuanced approach is to store a pointer telling what type it is with every node.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
/* Circular definitions mean one has to forward declare. */
struct node;
static void foo_print(const struct node *);
static void bar_print(const struct node *);
/* Virtual table stores the type of node. */
typedef void (*print_fn)(const struct node *);
static const struct vt { print_fn print; }
foo_vt = { &foo_print }, bar_vt = { &bar_print };
/* A list of nodes. */
struct node { struct node *next; const struct vt *vt; };
struct list { struct node *head; };
/* Subclasses of node. */
struct foo_node {
struct node base;
int id, age;
};
struct bar_node {
struct node base;
int id;
};
/* Implementations of the above. */
static void foo_print(const struct node *node) {
const struct foo_node *ptr = (const struct foo_node *)node;
printf("(foo)%d age %d", ptr->id, ptr->age);
}
static void bar_print(const struct node *node) {
const struct bar_node *ptr = (const struct bar_node *)node;
printf("(bar)%d", ptr->id);
}
static struct node *foo_input(void) {
int id, age;
struct foo_node *foo;
if((printf("Id: "), scanf(" %d", &id) != 1) || id == -1
|| (printf("Age: "), scanf(" %d", &age) != 1)
|| !(foo = malloc(sizeof *foo))) return 0;
foo->base.vt = &foo_vt;
foo->id = id;
foo->age = age;
fprintf(stderr, "User entered %d, %d.\n", foo->id, foo->age);
return &foo->base;
}
static struct node *bar_input(void) {
int id;
struct bar_node *bar;
if((printf("Id: "), scanf(" %d", &id) != 1) || id == -1
|| !(bar = malloc(sizeof *bar))) return 0;
bar->base.vt = &bar_vt;
bar->id = id;
fprintf(stderr, "User entered %d.\n", bar->id);
return &bar->base;
}
//address of the first node in the linked list
static void push(struct list *start, struct node *node) {
assert(start && node);
node->next = start->head, start->head = node;
}
static void printAll(const struct list *list) {
struct node *node;
for(node = list->head; node; node = node->next)
printf("%s", node == list->head ? "" : ", "), node->vt->print(node);
printf(".\n");
}
/** Interleaves the list `bars` with the list `foos`. `bars` will be the empty
list and `foos` will have all of the elements. */
static void createFinalList(struct list *foos, struct list *bars) {
/* Create this function. */
(void)foos, (void)bars;
}
int main(void) {
struct list foos = { 0 }, bars = { 0 };
struct node *node;
while(node = foo_input()) push(&foos, node);
while(node = bar_input()) push(&bars, node);
printf("foos: "), printAll(&foos);
printf("bars: "), printAll(&bars);
createFinalList(&foos, &bars);
printf("now,\n");
printf("foos: "), printAll(&foos);
printf("bars: "), printAll(&bars);
/* fixme: Memory leak, clean up. */
return 0;
}
If one really cannot modify the nodes, maybe encompass them in a union?
struct node {
const struct vt *vt;
union { struct nodeFB fb; struct nodeGS gs; };
};
I am trying to sort a doubly linked list in ascending order. I've gone trough the code again and again, and I can't find any logical flaws with it, so I assume the problem is elsewhere. When I try to print the sorted list, the console returns 0 without printing anything (the print function is not to blame, since it has already been tested)
Here is the code I am currrently running:
typedef struct dados_temp{
float temp;
float incerteza;
char pais[100];
char cidade[100];
float angle;
int hemisferio;
int dia;
int mes;
int ano;
} dados_temp;
typedef struct Node{
dados_temp payload;
struct Node *next;
struct Node *prev;
} Node;
//receives the original head pointer
//returns sorted list's head pointer
Node** SortDate(struct Node** head)
{
struct Node *i, *j;
for( i = head; i != NULL; i = i->next )//iterates over the entire list
{
//if the data value of the next node is bigger
if ( i->payload.ano > i->next->payload.ano )
{
//swaps the data value between i and i->next
//SwapNodes was tested and it is working
SwapNodes(i, i->next);
//the current value of i->next (former value of i)
//is compared to all the previous values
//and keeps swapping until a smaller value is found
for (j = i->next; j->payload.ano < j->prev->payload.ano;)
{
SwapNodes(j, j->prev);
}
}
}
return head;
}//sort
I know there probably are easier ways to sort doubly linked list, but I'm trying to figure out why this one doesn't work.
Thank you in advance!
EDIT:
showing all the involved functions:
#include <stdio.h>
#include <stdlib.h>
typedef struct dados_temp{
float temp;
float incerteza;
char pais[100];
char cidade[100];
float angle;
int hemisferio;
int dia;
int mes;
int ano;
} dados_temp;
typedef struct Node{
dados_temp payload;
struct Node *next;
struct Node *prev;
} Node;
Node * CreateCitiesList();
Node * CreateCountriesList();
Node * Intervalos(struct Node*, int[]);
void PrintBack(struct Node*);
struct Node* CreateNode (dados_temp x)
{
struct Node* NewNode = (struct Node*)malloc(sizeof(struct Node));
NewNode->payload = x;
NewNode->next = NULL;
NewNode->prev = NULL;
return NewNode;
}
}
void Print (struct Node* head)
{
struct Node* temp = head;
while ( temp != NULL)
{
printf("%d-%d-%d \n", temp->payload.ano, temp->payload.mes,
temp>payload.dia);
fflush(stdout);
temp = temp->next;
}
printf("\n");
}
Node* SortDate (struct Node*);
void SwapNodes (struct Node*, struct Node*);
int main(int argc, char* argv[])
{
CreateCountriesList();
}
Node* CreateCountriesList()
{
char linha[150] = {NULL};
char cabecalho[100] = {NULL};
int i = 0;
dados_temp New_Entry;
dados_temp tail;
int *ptr_head_co;
struct Node* head_countries = NULL;
struct Node* Node = NULL;
FILE *inputf;
inputf = fopen("tempcountries_all.csv", "r");
if (inputf == NULL)
{
printf("Nao da pa abrir o fitchas boi");
exit(EXIT_FAILURE);
}
//gets rid of the first line
fgets(cabecalho, 100, inputf);
for (i = 0; i < 577462 ; i++)
{
fgets(linha, 150, inputf);
//scans the date(amongst other things) from file (yyyy-mm-dd)
sscanf(linha, "%d-%d-%d,%f,%f,%[^,]s", &New_Entry.ano,
&New_Entry.mes,&New_Entry.dia, &New_Entry.temp, &New_Entry.incerteza,
&New_Entry.pais);
if (head_countries == NULL)
{
head_countries = CreateNode(New_Entry);
Node = CreateNode(New_Entry);
}
else
{
head_countries = InsertHead(head_countries, New_Entry);
}
}
fclose(inputf);
head_countries = RemoveNodes(Node);
SortDate(head_countries);
Print(head_countries);
return head_countries;
}
Node* SortDate(struct Node* head)
{
struct Node *i, *j;
for( i = head; i != NULL; i = i->next )
{
if ( i->payload.ano > i->next->payload.ano )
{
SwapNodes(i, i->next);
for (j = i->next; j->payload.ano < j->prev->payload.ano;)
{
SwapNodes(j, j->prev);
}
}
}
}//sort
void SwapNodes(struct Node* node1, struct Node* node2)
{
dados_temp temp = node1->payload;
node1->payload = node2->payload;
node2->payload = temp;
}
What should I do to allocate memory space for pNode->data, I want to put a single character into it, like pNode->data = "c". But it shows segmentation fault and the memory address for pNode->data is 0x1 which is out of bound.
Below is my code.
typedef struct node {
char* data;
int weight;
bool end_of_key;
struct node* left;
struct node* equal;
struct node* right;
} node_t;
typedef struct listnode{
char* data;
int weight;
struct listnode* next;
} listnode_t;
node_t* insert(node_t* pNode, char* word, int weight) {
if(pNode == NULL) {
/**
* Create a new pNode, and save a character from word
*/
pNode = (node_t*) malloc(sizeof(*pNode));
pNode->left = NULL;
pNode->equal = NULL;
pNode->right = NULL;
strcpy(pNode->data, word);
}
if(*word < *(pNode->data)) {
/**
* Insert the character on the left branch
*/
pNode->left = insert(pNode->left, word, weight);
}
else if(*word == *(pNode->data)) {
if(*(word+1) == '\0') {
/**
*set pNode end_of_key_flag to true and assign weight
*/
pNode->end_of_key = true;
pNode->weight = weight;
}
else {
/**
* If the word contains more characters, try to insert them
* under the equal branch
*/
pNode->equal = insert(pNode->equal, word+1, weight);
}
}
else {
/**
* If current char in word is greater than char in pData
* Insert the character on the right branch
*/
pNode->right = insert(pNode->right, word, weight);
}
return pNode;
}
From declaration of node, I can see that for data you are not assigning memory, you are just creating a pointer to character type, you can change the definition of node as follows(and code change is needed for the same)-
typedef struct node {
char data;
int weight;
bool end_of_key;
struct node * left;
struct node * equal;
struct node * right;} node_t;
I get a dereferencing pointer to incomplete type on line 58: rootNode->_left = NULL. Any ideas?
Also there is a lot of code commented out to single out this error but I have another question about the format of this ADT:
The usual Binary Search Tree structures out there that just have a Node class and all the BST functions such as insert take and return a node. Here however I have to use a separate Tree structure that has a root which is another structure TNode. This has been problematic for me for example in the addStringToTree function it only returns and takes a Tree parameter. So I don't know how to recurse on that in the usual way with Nodes. I created a helper function as my solution but not sure this is ideal.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
typedef struct TNode {
struct TNode* _left;
struct TNode* _right;
struct TNode* _key;
} TNode;
typedef struct Tree {
TNode* _root;
} Tree;
Tree* makeEmptyTree();
void destroyTree(Tree* root);
Tree* addStringToTree(Tree* t, char* value);
TNode* addStringToTreeHelper(TNode* node, char* value);
bool lookupInTree(Tree* t, char* value);
void traverse(TNode* root);
struct Tree* wordTree;
struct TNode* wordRoot;
int main() {
if(wordTree = makeEmptyTree()) {
printf("Tree initialized.\n");
/// traverse(wordTree->_root);
addStringToTree(wordTree, "peter");
//printf(wordTree->_root->_key);
//traverse(wordTree->_root);
} else {
printf("Error initializing tree.\n");
}
return 0;
}
Tree* makeEmptyTree() {
struct Tree* theTree = malloc(sizeof(struct Tree*)); // allocate memory for Tree
theTree->_root = NULL;
return theTree;
}
Tree* addStringToTree(Tree* t, char* value) {
if(t->_root == NULL) {
struct Tnode* rootNode = malloc(sizeof(struct TNode*));
rootNode->_left = NULL;
//rootNode = (TNode*)malloc(sizeof(struct TNode));
//strcpy(rootNode->_key, value);
// rootNode->_left = NULL;
// rootNode->_right = NULL;
//printf(rootNode->_key);
} else {
//addStringToTreeHelper(root, value);
}
return t;
}
TNode* addStringToTreeHelper(TNode* node, char* value) {
// node = malloc(sizeof(TNode)); // What is going on
if(strcmp(value, node->_key) < 0) {
node->_left = addStringToTreeHelper(node->_left, value);
} else if(strcmp(value, node->_key) > 0) {
node->_right = addStringToTreeHelper(node->_right, value);
}
return node;
}
void traverse(TNode* root) {
// if(root != NULL) {
// traverse(root->_left);
// printf("%s\n", root->_key);
// traverse(root->_right);
// } else {
// printf("Empty Tree\n");
// }
}
2nd Edit
Wow just a silly typo. Thanks guys. Also the _key variable of TNode should be of type char* instead of struct TNode* rolls eyes
struct Tnode* rootNode = malloc(sizeof(struct TNode*));
Should be
struct Tnode* rootNode = malloc(sizeof(struct TNode));
You're only allocating enough memory for a pointer and then pointing to it.
EDIT:
That should be TNode* rootNode not Tnode* rootNode.
Suppose I got an external library bst that handles custom data types insertion in a bst
Here are the new_node,insert and search functions :
//new node
struct bst_node* new_node(void* data)
{
struct bst_node* result = malloc(sizeof(struct bst_node));
assert(result);
result->data = data;
result->left = result->right = NULL;
return result;
}
//insert node
void insert(struct bst_node** root, void* data) {
struct bst_node** node = search(root, data);
if (*node == NULL) {
*node = new_node(data);
}
}
//search node
struct bst_node** search(struct bst_node** root, void* data) {
struct bst_node** node = root;
while (*node != NULL) {
if (data, (*node)->data < 0)
node = &(*node)->left;
else if (compare_result > 0)
node = &(*node)->right;
else
break;
}
return node;
}
and the main.c ,suppose i read the models from a txt file :
#include <stdio.h>
#include <stdlib.h>
#include "bst.h"
#include <string.h>
#define MAX 50
typedef struct data_t{
int gg,mm,aaaa;
}data;
typedef struct accesories_t{
char name[MAX];
int price;
struct accesories_t *next;
}accesories;
typedef struct model_t{
//int index;
char name[MAX];
char file_a[MAX];
data date;
int price;
accesories *acs;
}model;
int main(int argc, char *argv[])
{
int menu=0;
char nf[MAX];
char name[MAX];
char fa[MAX];
int price,gg,mm,a;
strcpy(nf,argv[1]);
FILE *fp=fopen(nf,"+r");
model m;
struct bst_node* root = NULL;
while(fscanf(fp,"%s %d//%d//%d %d %s",name,gg,mm,a,price,fa)!=EOF){
strcpy(m.name,name);
strcpy(m.file_a,fa);
m.date.gg=gg;
m.date.mm=mm;
m.date.aaaa=a;
m.price=price;
m.index=index++;
insert(&root ,m);
}
system("PAUSE");
return 0;
}
So my question arises in the search function, how can i manage a comparator on custom data (let's say insert the models ordered by name (strcmp) ?
I'm very confused on how can i pass the names to the bst.c given that bst.c has no idea how my model struct is made.
Should I modify the bst library and maybe on bst struct add before data some sort of index and use that as comparator ?
OK I've managed to fix that by adding a string key inside the struct bst
What I'm trying to achieve now is to return the void* data type casted into struct model,
suppose _I got the tree with nodes containing the data, once I do a search I'd like to return for
example the data contained in a node and work on it, any clues ????
tried someting like without any success
suppose node is a returned node from a search function
model *m;
m=(model*)node->data;
how could I achieve this?
Example for using compare functions as callbacks. Definitions omitted for brevity.
int llist_cmp(struct llist *l, struct llist *r)
{
if (!l) return 1;
if (!r) return -1;
return strcmp(l->payload,r->payload);
}
struct llist * llist_split(struct llist **hnd, int (*cmp)(struct llist *l, struct llist *r) )
{
struct llist *this, *save, **tail;
for (save=NULL, tail = &save; this = *hnd; ) {
if (! this->next) break;
if ( cmp( this, this->next) <= 0) { hnd = &this->next; continue; }
*tail = this->next;
this->next = this->next->next;
tail = &(*tail)->next;
*tail = NULL;
}
return save;
}
struct llist * llist_merge(struct llist *one, struct llist *two, int (*cmp)(struct llist *l, struct llist *r) )
{
struct llist *result, **tail;
for (result=NULL, tail = &result; one && two; tail = &(*tail)->next ) {
if (cmp(one,two) <=0) { *tail = one; one=one->next; }
else { *tail = two; two=two->next; }
}
*tail = one ? one: two;
return result;
}
BTW: the above snippet handles linked lists, but the mechanism for passing function pointers is the same as with trees, of course. And after all it was homework ;-)