I am doing a programming assignment at the moment and I dont really have a full grasp of linking as we havent covered it yet. However I feel I need it to do what I want as arrays are not sufficent
I have created a struct as follows
struct node
{
float coef;
int expo;
struct node *link;
};
from this I can create pointers to the struct each with different names, however the problem I encountered is that I want user input to determine the amount I structs. I also want the ability to add and create the different structs.
You need to create a head pointer to keep track of your list.
This might be helpful:
struct list
{
struct node *head;
int count;
};
And you need to allocate memory for each new node and move the head to the newly created one.
struct node *add_node(struct list *pList, float coef, int expo)
{
if (pList == NULL)
{
return NULL;
}
struct *node pNode = (struct node*)malloc(sizeof(struct node));
if (node == NULL)
{
return NULL;
}
pNode->coef = coef;
pNode->expo = expo;
pNode->link = pList->head;
pList->head = pNode;
pList->count++;
return pNode;
}
To delete an element you need to move the head forward and then free it previous memory.
void *delete_node(struct list *pList, float coef, int expo)
{
if (pList == NULL)
{
return NULL;
}
struct node *tmp = pList->head;
pList->head = pList->head->link;
free(tmp);
pList->count--;
}
Note:
This is not the ultimate version. I'm just pointing my fingers to what should be done.
I would try something like this as your data structure
struct node
{
float coef;
int expo;
struct node *link;
};
struct poly
{
node *value;
struct poly *link
}
Maintain a linked list of polys, each of which contains a linked list of nodes.
Related
typedef struct node {
int x;
struct node *next;
struct node **head;
} node;
Considering this struct, I've implemented a push function:
node *push(node *nodo, node *top) {
nodo->next = top;
top = nodo;
nodo->head = ⊤
return top;
}
so that every node is aware of who is the current head list.
But I have some problems when I have to delete the head of the list:
node *delete(node *top, int x) {
if (top->x == x)
return pop(top);
else
return *other function*;
}
node *pop(node *top) {
node *tmp = top;
top = tmp->next;
free(tmp);
return top;
}
When printing head content, this will give me segmentation fault:
void print(node *top) {
node *tmp = top;
printf("List:\n");
while (tmp != NULL) {
printf("%d\n", (*((tmp)->head))->x);
tmp = tmp->next;
}
printf("\nEnd\n");
}
But I have some problems when I have to delete the head of the list
You have much worse and more pervasive problems.
Here ...
node* push(node* nodo, node* top){
nodo->next=top;
top = nodo;
nodo->head = ⊤
return top;
}
You set nodo->head to point to a parameter of the function. The lifetime of that parameter ends when the function returns, at which time the node's head pointer becomes invalid. Undefined behavior results from any subsequent attempt to use the node's head pointer in any way.
I suppose that you have defined node.head as a double pointer so as to be able to change the head node in one place for all nodes. In that case, you need to choose a "one place" that is in fact the same for every node and whose lifetime does not end before that of the overall list does. Having chosen such a location, you would pass it itself to push:
node* push(node* nodo, node** top){
nodo->next = *top;
nodo->head = top;
*top = nodo;
return *top;
}
Of course, all callers would need to be updated appropriately.
However, if you want to have this kind of association between nodes and the list to which they belong, then you should consider creating a separate data structure for the list itself, and giving the nodes a poiunter to that. That would solve several problems for you.
Example:
typedef struct node{
int x;
struct node* next;
struct list* list;
}node;
struct list {
node *head;
// maybe other whole-list information, too, such as the tail node
// or an element count
};
The struct list objects then provide the place for head node pointers to be recorded, and nodes can access their lists' head node via the list.
I'm struggeling to get this task (Implementing a linked list) done. I tried to build a so called sentinel, which sould make it easier. My question is, how do I get access to the actual elements? I tried to print the roots value (44) but I only get weired values. I assume, that these are adresses of memory (e.g. 6893440).
#include<stdio.h>
struct node {
int val;
struct node* next;
};
struct node** init() {
struct node **l;
l = malloc(sizeof(struct node**));
*l = NULL;
return l;
}
void insert(struct node** l, int val) {
struct node* p;
if(*l == NULL) {
p = malloc(sizeof(struct node));
p->val = val;
p->next = *l;
*l = p;
}
}
void main() {
struct node* list;
list = init();
insert(list, 44); // create a (root)node with value 44
printf("%d", list->val); // e.g. 6893440
}
Thank you very much for your help.
You should declare the list as a double pointer to node.
struct node** list;
Then you can access the value of the first node with
(*list)->val
More info:
In the implementation in data types such as lists in C we often use 2 typedefs to help with the readability of the code and eliminate lots of asterisks and ampersands. These are:
typedef struct node* ListNode;
typedef ListNode* List;
By doing this, you can declare a list simply by:
List list;
Note that the implementation of the list functions also becomes more readable by replacing struct node* and struct node** appropriately.
Creating a list in C implementing SLL.
struct dat
{
char fname[20];
char lname[20];
};
typedef struct node_s
{
struct dat data;
struct node_s *next;
}NODE;
NODE *list=NULL;
NODE *list_create(struct dat *data)
{
NODE *node;
if(!(node=malloc(sizeof(NODE))))
{
return NULL;
}
node->data = data;
node->next = NULL;
return node;
}
NODE *list_insert_after(NODE *node, struct dat *data)
{
NODE *newnode;
newnode = list_create(data);
newnode->next = node->next;
node->next = newnode;
return newnode;
}
I cant find any good examples using SLL.
Now i have this append function now i will apply the two SLL functions, list_create and list_insert_after.
Is this correct?
void app(struct dat x)
{
FILE *fp;
fp=fopen("database.dat","a");
if(fp==NULL)
{
printf("file error");
}
if(fp!=NULL)
{
printf("enter lname: ");
gets(x.lname);
printf("enter fname: ");
gets(x.fname);
fprintf(fp,"%s %s\n",x.lname,x.fname);
if(list == NULL)
{
list=list_create((&x));
}
else
{
next=list_insert_after(list,&x);
}
}
fclose(fp);
}
To complete your example you should decide:
a) what if the role of your file database.dat.
b) how you work with your list.
I suppose you need two pointers to operate with the list: a pointer to the first element (it is list I think) and pointer to the last element (may be it is next).
Now call such as list_insert_after(list,&x); always inserts element after the first element, so your list cannot be longer than 2.
Consider the changes in your code as follows:
if(list == NULL)
{
list = list_create((&x));
next = list; // the last is the first
}
else
{
next=list_insert_after(next,&x); // insertion after the last
}
And about the file: if you decide to store not strings in text file, but structures in the binary file, save only struct dat to file, because storing pointers has no sense.
Even if C is a low level language, it is not forbidden to structure data. The node should be an internal object of the list. How to implement it in C depends on how you want to use it. Some examples :
a FIFO stack : 2 functions push and pop, and the list only needs to retain the last added element (you won't add after but before - left as an exercise)
a LIFO queue : still only 2 functions add and take, and the list needs to retain first element (its head) because its the next that will be taken, and last one (its tail) because it is where you will add next
typedef struct list_s {
NODE *head;
NODE *tail;
int len;
} LIST;
int add(LIST *list, struct dat *data) {
list->tail = list_insert_after(list->tail, data);
list->len += 1;
return list->len;
}
struct dat * take(LIST *list) {
if (list->len == 0) return NULL;
struct dat *data = head->data;
NODE *n = head;
head = head->next;
free(n);
return data;
}
of course, you will have to initialize a list, could take its length, ...
a true list : internally the same as a LIFO, but you will have to define an iterator (only contains a NODE *), and for example a BOOL hasnext(*ITERATOR) and struct dat * next(*ITERATOR)
the remaining is only limited by your requirements
NB: I assumed NODE.data was a struct dat * not a struct dat ...
typedef struct LIST{
int count = 0;
}LIST;
typedef struct NODE{
int data;
struct NODE *link;
}NODE;
int main() {
NODE *p1, *p2, *p3;
p1 = (NODE*)malloc(sizeof(NODE));
p1->link = NULL;
p2 = (NODE*)malloc(sizeof(NODE));
p2->data = 20;
p2->link = NULL;
p1->link = p2;
I want to make add NODE function and list to control NODE.
Give me some answer to solve this problem.
you should define head in the list.
node * head;
Insert function as follows, to insert value in ascending order.
void insert(int val)
{
node * nd = new node();
nd->val = val;
if(head == NULL)
head = nd;
else
{
if(val <= head->val)
{
nd->next = head;
head = nd;
}
else
{
node * itr = head;
while(itr->next != NULL && itr->next->val <= val)
itr = itr->next;
nd->next = itr->next;
itr->next = nd;
}
}
}
First you probably want to add to your LIST struct a field "NODE *first", which points to NULL initially, and then will point to the first element of your list.
Then what does you add function should do? Add to the beginning or the end of the list?
If at the beginning: allocate a NODE, set its link pointer to the first element of your list and say that the first element of the list is now the node that you just allocated.
Try to give variable according to their work, so that it is easy to understand.
struct node
{
int val;
struct node* next;
};
void insert(struct node** head_ref, int data)
{
struct node* new_node = (struct node*)malloc(sizeof(struct node));
new_node->val = data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
int main()
{
struct node* head = NULL;
insert(&head,1);
insert(&head,2);
return 0;
}
Note that : Insert function will always add the value at front.
Try to write function for particular task.
I'll avoid giving you the entire answer in C code since it's in general better to "teach a man to fish".
I would suggest that you add a NODE * member to your LIST class to store the header node of your linked list.
The addNode that adds a node to the next node should look like this:
void addNode (LIST* list, NODE * penultNode, int newData);
// list: Address to the linked list info object
// penultNode: Address to the node after which you want to add a new node.
// Should be NULL if your linkedlist is empty
// newData: Data in the new node that you wanna add
Inside this function, your actions will depend on whether penultNode is NULL or not. If it is not null, your job is simple. You just allocate a new NODE object and set the pointer of penultNode->next to the new object. If it is NULL, that means that no node exists in the list yet. In this case, you will need to set the pointer of list->headerNode to the new NODE object.
I am newbie in C and I am trying to write a linked list in which each node simply contains an int. The definition of the structure is ok, but I also want to write methods to update this linked list (add element at the tail and delete the head element). (I want to be able to read the most recently added element)
I wrote the functions below, but I don't know where the free should take place and how to implement it. Could anyone help me with this?
typedef struct Node{
Node next = NULL;
int number;
} Node;
void add_node(Node *LL,int val){
// add node to the end of the linked list
new_node = (struct Node *)malloc(1*sizeof(struct Node));
new_node->number = val;
Node n = *LL;
while (n.next != NULL){
n = n.next;
}
n.next = new_node;
}
void delete_head(Node *LL){
// update the head
*LL = LL->next;
//free?
}
void update_LL(*LL,int val){
add_node(*LL,val);
delete_head(*LL);
}
I rename your data structure this way:
struct pointer
{
int field;
struct pointer *link;
};
typedef struct pointer cell;
Then we can use this function for your need:
void ad_an_element_at_the_end_of_the_list()
{
cell *p=NULL;
cell *ptr=head;
int value;
cout<<" Integer number to insert at the end of the list: ";
cin>>value;
p=(cell*)malloc(sizeof(cell));
p->field=value;
p->link=NULL;
if(ptr==NULL)
{
ptr=p;
head=ptr;
}else
{
if(ptr->link==NULL) t
{
ptr->link=p;
head=ptr;
}else
{
while(ptr->link!=NULL)
{
ptr=ptr->link;
}
ptr->link=p;
}
}
}
Try changing *LL = LL->next; for Node *nextNode = LL->next;.
Then you can call free(LL) followed by LL = nextNode.
void delete_head(Node *LL){
Node *nextNode = LL->next;
free(LL);
LL = nextNode;
}
This then frees the Node at the head and moves the pointer to the next one in the Linked List.
You need to save your link to node which is next before you delete current node. Otherwise you won't be able to refer any node of your linkedlist. Now when you have backed up your link to next node, you can free current node pointed by LL, and then assign LL pointer to next node which you had earlier backed up in temp pointer.
Node *temp = LL->next;
free(LL);
LL = temp;
Possibly a duplicate of this question LinkedList - How to free the memory allocated using malloc
Basically you have to store the pointer to the node you want to delete otherwise you will leak that memory as there will be no reference to that memory location anywhere in your code.
try this in your delete_head function:
Node *temp = LL;
*LL = LL->next;
free(LL);
Hope this helps!