How can I restart a double linked list? - c

I'm coding a program to multiply two polynomials. I need some advice as to how I can restart the double linked list in the nested while loop in the polyProduct function. I mean, at this point I need to go back to the first position of the list. This is the code I have so far:
#include "DLListInterface.h"
#include <stdio.h>
#include <stdlib.h>
int numRead(DLnode*,int);
void printList(DLnode*);
DLnode *polyProduct(DLnode*,DLnode*);
int main()
{
DLnode *number1;
DLnode *number2;
DLnode *result;
int readval;
int numbterms;
int i;
scanf("%d",&numbterms);
scanf("%d",&readval);
/* initial DLnode of number1*/
number1=(DLnode*)malloc(sizeof(DLnode));
number1->value=readval;
number1->next=NULL;
number1->prev=NULL;
readval=numRead(number1,numbterms);
scanf("%d",&numbterms);
scanf("%d",&readval);
number2=(DLnode*)malloc(sizeof(DLnode));
number2->value=readval;
number2->next=NULL;
number2->prev=NULL;
readval=numRead(number2,numbterms);
printf("\n");
printList(number1);
printList(number2);
result=polyProduct(number1,number2);
printList(result);
getch();
return 0;
}
int numRead(DLnode*number,int numbterms)
{
int readval,i;
DLnode *anothernode;
for(i=0;i<(numbterms*2)-1;i++)
{
scanf("%d",&readval);
anothernode=(DLnode*)malloc(sizeof(DLnode));
anothernode->value=readval;
anothernode->next=NULL;
anothernode->prev=Dlast(number);
Dlast(number)->next=anothernode;
}
return readval;
}
DLnode *polyProduct(DLnode*poly1,DLnode*poly2)
{
DLnode *result;
DLnode *newnode;
DLnode *first;
first=poly2;
newnode=(DLnode*)malloc(sizeof(DLnode));
newnode->value=(poly1->value)*(poly2->value);
newnode->next=NULL;
newnode->prev=NULL;
result=newnode;
poly1=poly1->next;
poly2=poly2->next;
newnode=(DLnode*)malloc(sizeof(DLnode));
newnode->value=poly1->value+poly2->value;
newnode->next=NULL;
newnode->prev=Dlast(result);
Dlast(result)->next=newnode;
poly1=poly1->prev;
poly2=poly2->next;
while(poly1!=NULL)
{
while(poly2!=NULL)
{
newnode=(DLnode*)malloc(sizeof(DLnode));
newnode->value=(poly1->value)*(poly2->value);
newnode->next=NULL;
newnode->prev=Dlast(result);
Dlast(result)->next=newnode;
poly1=poly1->next;
poly2=poly2->next;
newnode=(DLnode*)malloc(sizeof(DLnode));
newnode->value=poly1->value+poly2->value;
newnode->next=NULL;
newnode->prev=Dlast(result);
Dlast(result)->next=newnode;
poly1=poly1->prev;
poly2=poly2->next;
}
poly1=poly1->next;
poly2=first; //restart poly 2
}
return result;
}
void printList(DLnode*number)
{
while (number!=NULL)
{
printf("%d ",number->value);
number=number->next;
}
printf("\n");
return;
}
//Declaration of DLnode in DLList.h file
typedef struct Dcontainer
{
int value;
struct Dcontainer *next;
struct Dcontainer *prev;
} DLnode;

One way of going to the start of the list is to manipulate the pointer to move to the start of the list
void seekstart(DLNode* number)
{
while(number->prev != null)
{
number = number->prev;
}
}
The other option is use temporary nodes to store the Starting node of the list before processing.
DLnode *temp_num1 = number1;
DLnode *temp_num2 = number2;
result=polyProduct(number1,number2);
Or You keep a pointer to the root in the structure of the node itself. Although this might not be an efficient solution. It is quite helpful if you need to access the starting of the list quite frequently
//Declaration of DLnode in DLList.h file
typedef struct Dcontainer
{
int value;
struct Dcontainer *next;
struct Dcontainer *prev;
struct Dcontainer *root; //root is the starting of the list
} DLnode;

Related

How can I fix this linked list output?

#include <stdio.h>
#include <stdlib.h>
struct node{
int sayi;
struct node* sonraki;
};
struct node* baslangic=NULL;
struct node* olustur(int sayi){
struct node* yenidugum=(struct node*)malloc(sizeof(struct node));
yenidugum->sayi=sayi;
yenidugum->sonraki=NULL;
return yenidugum;
}
void sonaekle(int sayi){
struct node* sonaeklenecek=olustur(sayi);
if(baslangic==NULL){
baslangic=sonaekle;
}
else
{
struct node* temp=baslangic;
while(temp->sonraki!=NULL){
temp=temp->sonraki;
temp->sonraki=sonaekle;
}
}
}
void yazdir(){
struct node* temp=baslangic;
while(temp!=NULL){
printf("%d =>",temp->sayi);
temp=temp->sonraki;
}
}
int main()
{
int secim, sayi;
while(1){
printf("1-Sona eleman ekle.....\n");
printf("Yapmak istediginiz secimi yapin...\n");
scanf("%d",&secim);
switch(secim){
case 1:
printf("Hangi elemani ekleyeceksiniz..\n");
scanf("%d",&sayi);
sonaekle(sayi);
yazdir();
break;
}
}
return 0;
}
I am trying to do make linked list but when I run this code it gives output like this:-443987883 =>. What is my mistake. I can't find it. Thank you for your answers and giving your time.
There are typos.
Instead of
baslangic=sonaekle;
where you are assigning the function pointer of the type void ( * )( int ) to the pointer of the type struct node * you need to write
baslangic=sonaeklenecek;
Instead of this while loop
while(temp->sonraki!=NULL){
temp=temp->sonraki;
temp->sonraki=sonaekle;
}
you need to write
while(temp->sonraki!=NULL){
temp=temp->sonraki;
}
temp->sonraki = sonaeklenecek;

I am learning data structures and stuck at implementation of queues using linked-list in c

I have written the below piece of code for implementing the queues and their operations(enqueue). The program compiled well with no errors but when the input is given for insertion(enqueue operation) the program stops working and shows a.exe has stopped working
The program contains create_node() function which returns a node, linkedlist initialize function, queue initialize function both of these functions are void functions, and insertion at the end of the linked list function is written which in turn calls the enqueue function.
Note: There's no display function to print all the elements to queue
I think there might be something wrong with initialization functions but I am not sure about it.
#include <stdlib.h>
#include <stdio.h>
typedef struct node node;
struct node
{
int id;
node *link;
};
typedef struct list
{
node *head;
node *tail;
int number_of_nodes;
} List;
typedef struct queue
{
List *ptr_list;
} Queue;
static node *create_node(int id,node *link)
{
node *temp = (node*)malloc(sizeof(node));
temp->id=id;
temp->link=link;
return temp;
}
void list_initialize(List *ptr_list)
{
ptr_list = (List*)malloc(sizeof(List));
ptr_list->head=ptr_list->tail=NULL;
ptr_list->number_of_nodes = 0;
}
void list_insert_rear(List *ptr_list, int id)
{L
node *temp = create_node(id,NULL);
if(ptr_list->tail==NULL)
{
ptr_list->head=ptr_list->tail=NULL;
ptr_list->number_of_nodes++;
}
else
{
ptr_list->tail->link=temp;
ptr_list->tail=temp;
ptr_list->number_of_nodes++;
}
}
void queue_initialize(Queue *queue_list)
{
queue_list = (Queue*)malloc(sizeof(Queue));
list_initialize(queue_list->ptr_list);
}
void queue_enqueue(Queue *ptr, int id)
{
list_insert_rear(ptr->ptr_list,id);
}
int main()
{
Queue queue;
queue_initialize(&queue);
int choice, id, t;
int loop = 1;
while (loop)
{
scanf("%d", &choice);
switch (choice)
{
case 0:
scanf("%d", &id);
queue_enqueue(&queue, id);
break;
default:
loop =0;
break;
}
}
}
This is a problem I actually ran in to a few times and can be tricky to spot. In list_initialize, you should use List **ptr_list.
In the first line of this function, you are changing the pointer, but only in the scope of this variable, so the pointer you put in doesn't actually point to the data anymore, this can be solved by making it a pointer to a pointer. (It's kinda hard to explain)
The function would be (didn't test it):
void list_initialize(List **ptr_list)
{
List *ptr_listnew;
ptr_listnew = (List*)malloc(sizeof(List));
ptr_listnew->head=ptr_listnew->tail=NULL;
ptr_listnew->number_of_nodes = 0;
*ptr_list = ptr_listnew;
}
This is also the case in queue_initialize, which requires the same kind of fix.
You are confusing/combining struct allocation and struct initialization so that your functions do neither well. (See my top comments). As a result, your struct pointers aren't initialized properly and you're getting UB (undefined behavior), most likely a SIGSEGV (segfault).
Although a single function can do both, separating them can give you some insight.
Side note: Don't cast the result of malloc. See: Do I cast the result of malloc?
Here's a refactored version. Original code is marked with #if 0 and new code is marked with #if 1. Bug/fixes are annotated.
#include <stdlib.h>
#include <stdio.h>
typedef struct node node;
struct node {
int id;
node *link;
};
typedef struct list {
node *head;
node *tail;
int number_of_nodes;
} List;
// NOTE/STYLE: use more descriptive names
typedef struct queue {
#if 0
List *ptr_list;
#else
List *queue_list;
#endif
} Queue;
static node *
create_node(int id, node *link)
{
node *temp = (node *) malloc(sizeof(node));
temp->id = id;
temp->link = link;
return temp;
}
void
list_initialize(List *ptr_list)
{
// NOTE/BUG: you are blowing away caller's pointer value
#if 0
ptr_list = malloc(sizeof(List));
#endif
ptr_list->head = ptr_list->tail = NULL;
ptr_list->number_of_nodes = 0;
}
#if 1
List *
list_create(void)
{
List *ptr_list;
ptr_list = malloc(sizeof(List));
list_initialize(ptr_list);
return ptr_list;
}
#endif
void
list_insert_rear(List *ptr_list, int id, int time)
{
node *temp = create_node(id, NULL);
if (ptr_list->tail == NULL) {
ptr_list->head = ptr_list->tail = NULL;
ptr_list->number_of_nodes++;
}
else {
ptr_list->tail->link = temp;
ptr_list->tail = temp;
ptr_list->number_of_nodes++;
}
}
void
queue_initialize(Queue *queue_list)
{
// NOTE/BUG: you are blowing away caller's pointer value
#if 0
queue_list = malloc(sizeof(Queue));
#endif
queue_list->queue_list = list_create();
}
#if 1
Queue *
queue_create(void)
{
Queue *queue_list;
queue_list = malloc(sizeof(Queue));
queue_initialize(queue_list);
return queue_list;
}
#endif
// NOTE/BUG: wrong prototype
#if 0
void
queue_enqueue(Queue *queue, int id)
#else
void
queue_enqueue(Queue *queue, int id, int time)
#endif
{
// NOTE/BUG: not enough arguments for call
#if 0
list_insert_rear(queue->queue_list, id);
#else
list_insert_rear(queue->queue_list, id, time);
#endif
}
int
main(void)
{
Queue queue;
queue_initialize(&queue);
int choice, id, t;
int loop = 1;
#if 1
t = 0;
#endif
while (loop) {
scanf("%d", &choice);
switch (choice) {
case 0:
scanf("%d", &id);
queue_enqueue(&queue, id, t);
++t;
break;
default:
loop = 0;
break;
}
}
#if 1
return 0;
#endif
}

How to print a value in a struct pointer pointed for other struct?

Considering that i have two structs, where one point to other, how could i print a vallue from the second struct, caliing the first?
A brief explanation of the program bellow:
NODE, a struct that points to itselft to make a pile and to a generic pointer
ALUNO, the struct that the generic pointer in NODE will point to
createNode, function that allocates memory for the nodes
preencherNode, fills the pointer of node with the respective ALUNO
pushNode, creates a new node, pointing to the last created one, making a pile
criarAluno, allocates memory for ALUNO and fills it camps.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int id;
float media;
} ALUNO;
typedef struct node
{
void *pointer;
struct node* link;
} NODE;
NODE* createNode(void)
{
NODE* topo;
topo=(NODE*)malloc(sizeof(NODE));
topo->pointer = NULL;
topo->link = NULL;
return(topo);
}
NODE* pushNode (NODE* topo)
{
NODE* novo;
novo=createNode();
novo->link=topo;
topo = novo;
return(topo);
}
NODE* preencherNode (NODE* topo, ALUNO* data)
{
topo->pointer=data;
return(topo);
}
ALUNO* criarAluno(FILE* v)
{
ALUNO* aln;
aln=(ALUNO*)malloc(sizeof(ALUNO));
int x;
float y1,y2;
fscanf (v, "%d %f %f",&x,&y1,&y2);
aln->id=x;
y1=(y1+y2)/2;
aln->media=y1;
return(aln);
}
void printData (NODE* topo)
{
NODE* aux;
aux=topo;
ALUNO* aln;
while(aux->link!=NULL)
{
aln=((ALUNO*)(aux->link));
printf("ID: %d \n",aln->id);
printf("Media: %f \n",aln->media);
printf("........................ \n");
aux=aux->link;
}
}
void main ()
{
FILE *doc;
doc = fopen("documento.txt","r");
if (doc==NULL){
printf("Nao ha como abrir o arquivo");
return(-1);
}
NODE *pilha;
pilha=createNode();
ALUNO* aluno;
int x;
for(x=0;x<11;x++)
{
aluno=criarAluno(doc);
pilha=preencherNode(pilha,aluno);
pilha=pushNode(pilha);
}
printData(pilha);
}
So now, the function printData, is printing the allocated space memory of the value i want, but not the value.
Given as stated in question that you have NODE *node....
ALUNO *aluno;
aluno = (ALUNO *)(node->pointer)
printf("%d", aluno->id)

Declaration of variable, simple linked list

#include <stdio.h>
#include <stdlib.h>
struct node
{
char name[30];
int age;
struct node *next;
} *list_head,*neos;
main()
{
}
void add_node_to_the_list(char data1[],int data2)
{
neos=(struct node *)malloc(sizeof(struct node));
strcpy(neos->name,data1);
age=data2;
neos->next=list_head;
list_head=neos;
}
void display_list()
{
struct node *p;
p=list_head;
while(p!=NULL)
{
puts(p->name);
printf("%d\n",age);
p=p->next;
}
}
When I compile this code I get an error because I haven't declare the "age" variable, although I have done that inside the struct node, outside the main function. Why?
Here you go:
#include <stdio.h>
#include <stdlib.h>
struct node
{
char name[30];
int age;
struct node *next;
}*list_head,*neos;
main()
{
}
void add_node_to_the_list(char data1[],int data2)/*Ç óõíáñôçóç áõôç ðñïóèåôåé êïìâï óôç ëéóôá*/
{
neos=(struct node *)malloc(sizeof(struct node));
strcpy(neos->name,data1);
neos->age=data2; //the correction is made here
neos->next=list_head;
list_head=neos;
}
void display_list()
{
struct node *p;
p=list_head;
while(p!=NULL)
{
puts(p->name);
printf("%d\n",p->age); //and here
p=p->next;
}
}
Note that you have been trying to access a struct element without pointing it.
Replace age=data2; by neos->age = data2;
and replace printf("%d\n",age); by printf("%d\n", p->age);
There is no age variable, age is a member of struct node.
You have declared it in a structure so to access it you have to pass by your structure
neos->age
age is just an element in a structure.
So assuming we have a structure defined as the following:
struct PlaceHolder {
int int_element
char char_element
} * place_holder;
to access any of the elements you need to access the structure first and reference the element in that structure.
place_holder->int_element = 5;
place_holder->char_element = "a";
In your case you have both list_head and neos as global variables, so to access an element in any of them you have to do:
list_head->age = data2;
neos->age = data2;

creating a queue of pointers in c

i have a dynamic number of pointers all having the same size. i need to store all the addresses of my pointers in some place like a link List in order to fetch them later on.
my question is what structs should i use. is the following correct:
struct Node{
int *k;
Node*Next;
}
struct LS{
Node*first,*last;
void push(Node*n);
Node* GetFirst();
Node* GetLast();
}
the LS is the linked list that stores Nodes. and a Node is a struct that holds the address of my pointer and a pointer to the next Node.
am i using int *k to store the address of my pointer correctly? should i continue with this implementation or is there any easier way to do this?
this sample code may help you start...
#include <stdio.h>
struct Node{
int *k;
Node *Next;
}* Temp;
struct LS
{
Node *first,*last;
void push(Node *MyNode)
{
MyNode->Next=NULL;
if(empty())
{
first=MyNode;
last=MyNode;
}
else
{
last->Next = MyNode;
last=MyNode;
}
}
Node* front()
{
return first;
}
void pop()
{
free(first->k);
first=first->Next;
}
bool empty()
{
if(first==NULL) return true;
return false;
}
};
int N=10;
int main()
{
LS Q;Q.first=NULL;
for(int i=0;i<3;i++)
{
Node *NewNode= (Node*)malloc(sizeof(Node));
NewNode->k = (int*)malloc(sizeof(int)*N);
for(int k=0;k<N;k++) NewNode->k[k]=i;
Q.push(NewNode);
}
while(!Q.empty())
{
Temp=Q.front();
for(int i=0;i<N;i++) printf("%d ",Temp->k[i]);
printf("\n");
Q.pop();
}
return 1;
}
Yes, your Node struct is correct.
As to whether there is an easier way it depends. If there is a maximum number of pointers that you will need then an array of pointers would be easier. If you can do it in C++ then an STL vector (can use it like an array, but underneath the hood it can grow dynamically as needed) is easier. If you have to do it in C and it has to be dynamic, though, then no, there is not an easier way.
WDM.H (microsoft header) has a bunch of linked list stuff to look at ( http://msdn.microsoft.com/en-us/library/ff547799(VS.85).aspx ) , I've cut and pasted from that, and added a very simple example.
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY;
typedef struct _MY_THING
{
LIST_ENTRY ListEntry;
ULONG randomdata1;
ULONG randomdata2;
ULONG randomdata3;
ULONG randomdata4;
} MY_THING, *PMY_THING;
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(PCHAR)(address) - \
(ULONG_PTR)(&((type *)0)->field)))
VOID
InsertHeadList(
IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry
)
{
PLIST_ENTRY Flink;
Flink = ListHead->Flink;
Entry->Flink = Flink;
Entry->Blink = ListHead;
Flink->Blink = Entry;
ListHead->Flink = Entry;
}
VOID
InitializeListHead(
IN PLIST_ENTRY ListHead
)
{
ListHead->Flink = ListHead->Blink = ListHead;
}
PLIST_ENTRY
RemoveHeadList(
IN PLIST_ENTRY ListHead
)
{
PLIST_ENTRY Flink;
PLIST_ENTRY Entry;
Entry = ListHead->Flink;
Flink = Entry->Flink;
ListHead->Flink = Flink;
Flink->Blink = ListHead;
return Entry;
}
void main()
{
LIST_ENTRY HeadOfMyList;
MY_THING Thing;
InitializeListHead(&Head);
// example of add thing to list.
InsertHeadList(&HeadOfMyList, &Thing.ListEntry);
// example of removing thing from the list
PLIST_ENTRY listEntry = RemoveHeadList(&HeadOfMyList);
PMY_THING pThing = (PMY_THING) CONTAINING_RECORD(listEntry, MY_THING, ListEntry);
}

Resources