#include <stdio.h>
#include <stdlib.h>
// A Tree node
typedef struct leaf
{
char ch;
int freq;
struct leaf *left, *right;
}leaf;
typedef struct node{
int data;
leaf* leaf_data;
struct node *ptr;
} node;
//----- LINKED LIST -----
struct LinkedList {
node* head;
//node* tail;
};
typedef struct LinkedList LinkedList_s;
leaf* createLeaf(char ch, int freq)
{
leaf* node = malloc(sizeof(leaf));
node->ch = ch;
node->freq = freq;
node->left = NULL;
node->right= NULL;
return node;
}
//----- CREATE LINKED LIST -----
LinkedList_s createSortedList()
{
LinkedList_s list = {NULL};
return list;
}
node* createStackNode(leaf* l){
node* temp = (node*) malloc(sizeof(node)) ;
temp->data = (int) l->freq;
temp->leaf_data = l;
return temp;
}
void insert(LinkedList_s* head, node* l) {
if(head->head == NULL){
head->head = l;
}
else if (head->head->data > l->data){
l->ptr = head->head;
head->head = l;
}
else{
node *prev = (node*)malloc(sizeof(node));
node *next = (node*)malloc(sizeof(node));
int i = 0;
prev = NULL;
next = head->head;
while(next != NULL && i == 0){
if (next->data >= l->data){
prev->ptr = l;
l->ptr = next;
i = 1;
}
prev = next;
next = next->ptr;
}
if (next == NULL){
prev->ptr = l;
l->ptr = next;
}
}
}
node* dequeue(LinkedList_s *list){
node* temp = (node*)malloc(sizeof(node));
temp = list->head;
list->head = list->head->ptr;
return temp;
}
void insertLeaf(LinkedList_s *list, leaf* l){
node* n = createStackNode(l);
//printf("%d", n->data);
insert(list, n);
}
basically I'm building a huffman encoder for a class project and I'm trying to create a sorted list/priority queue to store BTS leaf node in order of frequency. I'm having problems with createStackNode. If I change the node struct int data to int* data I don't get a seg. fault, but this way it randomly seg. faults and won't sort. Any ideas would be much appreciated!
So I call insertLeft from a separate file
#include <stdio.h>
#include <stdlib.h>
#include "Sorted_List.h"
#include "linked_counter.h"
int main(void){
//Make a Frequency List
LinkedList_t* x = malloc(sizeof(LinkedList_t));
x = makeList();
//Create a Sorted List/Priority Queue
struct LinkedList_s* list = malloc(sizeof(LinkedList_s));
*list = createSortedList();
leaf* l = malloc(sizeof(leaf));
//Current node for traversal
Node_t* current = malloc(sizeof(Node_t));
current= x->head;
while(current != NULL){
l = createLeaf(current->data, current->count);
printf("%c %d ->",l->ch, l->freq);
insertLeaf(list, l);
current= current->next;
}
//for(int i = 0; i < 5; i++)
//printf("%c~~\n", list->head->leaf_data->ch);
}
at insert leaf it gives the fault
Related
I am trying to implement a deque in C. I am learning C, so the error might seem very trivial. Here's the entire program
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *prev;
struct node *next;
}Node;
Node *getNode(int data){
Node *temp = (Node *)malloc(sizeof(Node));
temp -> next = temp -> prev = NULL;
temp -> data = data;
return temp;
}
void push_right(Node **head, Node **tail, int data){
Node *newNode = getNode(data);
Node *temp = (*head);
if (temp == NULL){
*head = newNode;
}
else{
while(temp -> next != NULL){
temp = temp -> next;
}
temp -> next = newNode;
newNode -> prev = temp;
*tail = newNode;
}
}
void push_left(Node **head, Node **tail, int data){
Node *newNode = getNode(data);
Node *temp = (*head);
if (temp == NULL){
*head = newNode;
}
else{
newNode -> next = temp;
newNode -> prev = NULL;
(*head) = newNode;
}
}
void remove_right(Node **head, Node **tail, int *val){
Node *temp = (*tail);
if (temp == NULL)
{
printf("Cannot be removed doesn't point to anything\n");
return;
}
else{
*val = temp -> data;
temp = temp -> prev;
(*tail) = temp;
}
free(temp);
}
void remove_left(Node **head, Node **tail, int *val){
Node *temp = (*head);
if (temp == NULL)
{
printf("Cannot be removed doesn't point to anything\n");
return;
}
else{
*val = temp -> data;
temp = temp -> next;
(*tail) = temp;
}
free(temp);
}
void print_all(Node *head){
Node *temp = head;
printf("\n");
while(temp != NULL){
printf("%d\n",temp->data);
temp = temp -> next;
}
}
int main(int argc, char const *argv[])
{
int *val = NULL;
Node *head = NULL;
Node *tail = NULL;
for (int i = 0; i < 10; ++i){
push_right(&head, &tail,i);
push_left(&head, &tail,i);
}
remove_left(&head, &tail, val);
print_all(head);
return 0;
}
The problem seems to arise when remove_left() is called. I have spend a significant amount of time to understand where the problem is coming from but nothing seems to work. Please help.
This is the output on the Terminal screen.
lib2s-iMac:queue admin$ ./a.out
Segmentation fault: 11
Problem is here :
*val = temp -> data;
Val is NULL, so trying to dereference it will result in segmentation fault.
If you change val type to an int instead of a pointer to an int. And then call remove_left like this :
int main(int argc, char const *argv[])
{ int val = 0;
Node *head = NULL;
Node *tail = NULL;
for (int i = 0; i < 10; ++i){
push_right(&head, &tail,i);
push_left(&head, &tail,i);
}
remove_left(&head, &tail, &val);
print_all(head);
return 0;
}
This should work.
In your program have 3 main mistakes .
At int *val = NULL; Here it should be int val not int *val.
At function remove_left() . Here You should edit (*head) not (*tail).Also pointer (next,perv) are not managed properly.
Same in the case of remove_right(). Mistakes in managing pointers.
Modified Functions :-
void remove_right(Node **head, Node **tail, int *val) // modified This function.
{
Node *temp = (*tail);
if (temp == NULL)
{
printf("Cannot be removed doesn't point to anything\n");
return;
}
else
{
*val = temp->data;
temp->prev->next = NULL;
(*tail) = temp->prev;
}
free(temp);
}
void remove_left(Node **head, Node **tail, int *val) // modified This function.
{
Node *temp = (*head);
if (temp == NULL)
{
printf("Cannot be removed doesn't point to anything\n");
return;
}
else
{
*val = temp->data;
temp->next->prev = NULL;
(*head) = temp->next;
}
free(temp);
}
Modified main() :-
int main(int argc, char const *argv[])
{
int val = -1; // Modified here
Node *head = NULL;
Node *tail = NULL;
for (int i = 0; i < 10; ++i)
{
push_right(&head, &tail, i);
push_left(&head, &tail, i);
}
remove_left(&head, &tail, &val);
print_all(head);
return 0;
}
Complete code Online.
Output :-
8
7
6
5
4
3
2
1
0
0
1
2
3
4
5
6
7
8
9
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;
}
I want an array of linked List and obviously each linked should have separate head node. Initially, as an example, I am starting with one array element. I am storing linkedlist into current[0] . But it is giving segmentation fault. If I use Node *current it will create a list and working fine. But, I want to store the list within array. What is wrong with the code ?
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
Node *current[20];
void insert_beg_of_list(Node *current[0], int data);
void print_list(Node *current[0]);
void insert_beg_of_list(Node *current[0], int data) {
//keep track of first node
Node *head = current[0];
while(current[0]->next != head) {
current[0] = current[0]->next;
}
current[0]->next = (Node*)malloc(sizeof(Node));
current[0] = current[0]->next;
current[0]->data = data;
current[0]->next = head;
}
void print_list(Node *current[0]) {
Node *head = current[0];
current[0] = current[0]->next;
while(current[0] != head){
printf(" %d ", current[0]->data);
current[0] = current[0]->next;
}
}
int main() {
Node *head = (Node *)malloc(sizeof(Node));
head->next = head;
int data = 0 ;
int usr_input = 0;
int i;
int m;
int j;
scanf("%d", &usr_input);
for (i=0; i<usr_input; i++) {
scanf("%d", &data);
insert_beg_of_list(head, data);
}
printf("The list is ");
print_list(head);
printf("\n\n");
return 0;
}
I think you have mixed the global array current's use. Change your code to this :
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
void insert_beg_of_list(Node *current, int data);
void print_list(Node *current);
void insert_beg_of_list(Node *current, int data) {
//keep track of first node
Node *head = current;
while(current->next != head) {
current = current[0]->next;
}
current->next = malloc(sizeof(Node));
if (current->next == NULL)
return;
current = current->next;
current->data = data;
current->next = head;
}
void print_list(Node *current) {
Node *head = current;
current = current->next;
while(current != head){
printf(" %d ", current->data);
current = current->next;
}
}
int main() {
Node *current[20];
Node *head = malloc(sizeof(Node));
if (head == NULL)
return;
head->next = head;
int data = 0 ;
int usr_input = 0;
int i;
int m;
int j;
scanf("%d", &usr_input);
for (i = 0; i < usr_input; i++) {
scanf("%d", &data);
insert_beg_of_list(head, data);
}
//assign the newly created pointer to a place in the array
current[0] = head;
printf("The list is ");
print_list(head);
printf("\n\n");
return 0;
}
Keep in mind that the parameter current in your functions' prototypes and declarations is not the same as the array current created in your main function. I just left the name as it was.
NOTE : You should do something with head->next pointer, initialize it.
Also read this link on why not to cast the result of malloc and another one on why you should check its result.
You probably want this:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
void insert_beg_of_list(Node *current, int data);
void print_list(Node *current);
void insert_beg_of_list(Node *current, int data) {
//keep track of first node
Node *head = current;
while (current->next != head) {
current = current->next;
}
current->next = (Node*)malloc(sizeof(Node));
current = current->next;
current->data = data;
current->next = head;
}
void print_list(Node *current) {
Node *head = current;
current = current->next;
while (current != head) {
printf(" %d ", current->data);
current = current->next;
}
}
Node *NewList()
{
Node *newnode = (Node *)malloc(sizeof(Node));
newnode->next = newnode;
}
int main() {
Node *arrayofheads[20];
// We are using only arrayofheads[0] in this example
arrayofheads[0] = NewList();
int data = 0;
int usr_input = 0;
int i;
scanf("%d", &usr_input);
for (i = 0; i<usr_input; i++) {
scanf("%d", &data);
insert_beg_of_list(arrayofheads[0], data);
}
printf("The list is ");
print_list(arrayofheads[0]); printf("\n\n");
return 0;
}
I am trying to sort a Linked list, but not able to do it. Below is my code. Can anyone help me. I have seen some programs too, which sort linked list and their approach is also like this only.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
int push(struct node **h, int x)
{
struct node *temp = (struct node*)malloc(sizeof(struct node));
temp->data = x;
temp->next = *h;
*h = temp;
return 0;
}
void print(struct node *head)
{
struct node *temp = head;
while(temp != NULL)
{
printf("%d ",temp->data);
temp = temp->next;
}
printf("\n");
}
void sort(struct node **h)
{
int i,j,a;
struct node *temp1;
struct node *temp2;
for(temp1=*h;temp1!=NULL;temp1=temp1->next)
{
for(temp2=temp1->next;temp2!=NULL;temp2=temp2->next)
{
a = temp1->data;
temp1->data = temp2->data;
temp2->data = a;
}
}
}
int main()
{
struct node * head = NULL;
push(&head,5);
push(&head,4);
push(&head,6);
push(&head,2);
push(&head,9);
printf("List is : ");
print(head);
sort(&head);
printf("after sorting list is : ");
print(head);
return 0;
}
Below is the output which i am getting :
List is : 9 2 6 4 5
after sorting list is : 5 4 6 2 9
You're switching the elements no matter what. Compare them first and then swap them if temp2 is less than temp1:
void sort(struct node **h)
{
int i,j,a;
struct node *temp1;
struct node *temp2;
for(temp1=*h;temp1!=NULL;temp1=temp1->next)
{
for(temp2=temp1->next;temp2!=NULL;temp2=temp2->next)
{
if(temp2->data < temp1->data)
{
a = temp1->data;
temp1->data = temp2->data;
temp2->data = a;
}
}
}
}
In your bubble sort, you forget the swap condition.
In my opinion, I suggest insertion sort
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
int push(struct node **h, int x)
{
struct node *temp = (struct node*)malloc(sizeof(struct node));
temp->data = x;
if (*h == NULL) {
temp->next = *h;
*h = temp;
} else {
struct node *tmp = *h;
struct node *prev = NULL;
while (1) {
if (tmp == NULL || tmp->data >= temp->data)
break;
prev = tmp;
tmp = tmp->next;
}
temp->next = tmp;
if (prev != NULL)
prev->next = temp;
else
*h = temp;
}
return 0;
}
void print(struct node *head)
{
struct node *temp = head;
while(temp != NULL)
{
printf("%d ",temp->data);
temp = temp->next;
}
printf("\n");
}
int main()
{
struct node * head = NULL;
push(&head,5);
push(&head,4);
push(&head,6);
push(&head,2);
push(&head,9);
printf("List is : ");
print(head);
//sort(&head);
printf("after sorting list is : ");
print(head);
return 0;
}
I'm trying to count the number of times a given int occurs in a list, but I'm having a difficult time getting my pointers to work. Can someone spot where is my logic failing? Is it because of how I'm implementing the "follows" "->" in the counting function?
//this is in my .h file
typedef struct list_struct LIST;
///// the rest is in my .c file
typedef struct node {
ElemType val;
struct node *next;
} NODE;
struct list_struct {
NODE *front;
NODE *back;
};
//this is my counting function
int lst_count(LIST *l, ElemType x) {
LIST *current = l;
int count = 0;
while (current != NULL) {
if ((current->front->val) == x) count++;
current = current->front->next;
//in the line above I get the following warning:
//"incompatible pointer types assigning to 'LIST*' (aka 'struct list_struct*') from 'struct node*'"
}
return count;
}
Your problem is in the while loop
You are in a list struct, then you do
current->front->next;
Now you are in a NODE type struct, in the next iteration there is no front in NODE.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node *next;
struct node *previous;
} NODE;
int lst_count(NODE *l, int x) {
NODE *current = l;
NODE *start = current; /* so that we wont loose the start*/
int count = 0;
while (current != NULL) {
if ((current->val) == x)
count++;
current = current->next;
}
return count;
}
int main()
{
NODE* p = (NODE*)malloc(sizeof(NODE));
NODE* p1 = (NODE*)malloc(sizeof(NODE));
NODE* p2 = (NODE*)malloc(sizeof(NODE));
NODE* start = p;
p->val = 5;
p->next = p1;
p1->next = p2;
p2->next=NULL;
p1->val = 5;
p2->val = 5;
printf("%d", lst_count(start, 5));
}
I got the function to work thanks to your all advises
int lst_count(LIST *l, int x) {
NODE *current = l->front;
int count = 0;
while (current != NULL) {
if ((current->val) == x) count++;
current = current->next;
}
return count;
}