I need to write a function that returns the size of a linked list. It seems simple enough, but I get an exception when I try to advance my pointer.
This is the code:
int List_size(List *list)
{
List_node *p;
int counter = 0;
p = list->head;
while (p != NULL)
{
p = p->next;
counter = counter + 1;
}
return counter;
}
This is the code that defines the linked list:
typedef struct List_node
{
int data;
struct List_node *next;
struct List_node *prev;
}List_node;
typedef struct List
{
List_node *head;
}List;
And this is the code that creates the list:
List *create_list(int n)
{
List *list = (List*) calloc(n,sizeof(List));
list->head = NULL;
return list;
}
Lastly, I have inserted data (numbers) into the list using these two functions: (so don't think the lists are empty).
void insert_first(List_node *x, List *list)
{
x->next = list->head;
list->head = x;
}
void insert(List_node *x, List_node *y)
{
x->next = y->next;
y->next = x;
}
List_node *mk_node(int data, int n)
{
List_node *node = (List_node *)calloc(n, sizeof(List_node));
node->data = data;
return node;
}
Using a breakpoint I discovered that the problem lies in p = p->next, but I don't understand why.
Thank you very much.
edit - I did not think the full code is necessary, but here it is:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include "List.h"
void merge(List *small_list, List *big_list)
{
List_node *x, *y;
y = small_list->head;
x = big_list->head;
t = x->prev;
// while (y < x) //If there are smaller numbers on the small list, insert them first
// {
// insert(y,t)
// t = t->next;
// y = y->next;
// }
while (y != NULL && x->next != NULL)
{
if (x <= y && x->next >= y)
{
insert(y, x);
y = y->next;
}
else
x = x->next;
}
while (y != NULL)
{
insert(y, x);
y = y->next;
}
}
void main()
{
List *L1, *L2, *big_list, *small_list;
int num1, num2;
int i;
int a, b;
create_list(5,&L1);
create_list(3,&L2);
printf("Insert first number into L1\n");
scanf("%d", &num1);
node = mk_node(0,5);
insert_first(node, &L1);
for (i = 0; i<5; i++)
{
printf("Now insert the rest of the numbers\n");
scanf("%d", &num1);
next = mk_node(&num1,5);
insert(next, node);
node = next;
}
printf("Insert first number into L2\n");
scanf("%d", &num2);
node = mk_node(0,3);
insert_first(node, &L2);
for (i = 0; i<3; i++)
{
printf("Now insert the rest of the numbers\n");
scanf("%d", &num2);
next = mk_node(&num2,3);
insert(next, node);
node = next;
}
//If lists are in descending order, reverse them to ascending order
//if (L1->head > L1->head->next)
// reverse(L1);
// if (L2->head > L2->head->next)
// reverse(L2);
int size_L1 = List_size(L1);
int size_L2 = List_size(L2);
if (size_L1 <= size_L2)
{
big_list = L2;
small_list = L1;
}
else
{
big_list = L1;
small_list = L2;
}
merge(small_list, big_list);
print_list(L3);
getchar(); getchar();
}
As you can see, I inserted the numbers using the function insert(). I hope it is okay.
The function reverse is: (I really hope it works, I translated it from pseudo-code)
List reverse(List *list)
{
List_node *x, *y, *z;
if (list->head == NULL || list->head->next == NULL)
{
return *list;
}
x = list->head;
y = list->head->next;
z = list->head->next->next;
x->next = NULL;
while (z != NULL)
{
y->next = x;
x = y;
y = z;
z = z->next;
}
y->next = x;
list->head = y;
}
Basically, this is an assignment that says I have two 2-directional sorted linked lists, and I'm supposed to merge them into one big sorted linked list.
As for the exception - Unhandled exception at 0x00E21766 in Lists.exe: 0xC0000005: Access violation reading location 0xCCCCCCD0.
Edit - the print_list function:
void print_list(List *list)
{
List_node *p;
p = list->head;
printf("The linked list consists of: ");
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
The problem is in code you did not show, because all the code you give is fine (*).
I could use your structs and functions to :
create a List
add a first node (with insert_first)
add other nodes (with insert)
get the size (using List_size)
display the data value of every node
free the nodes and the list
Here's the full code :
#include <stdio.h>
#include <malloc.h>
typedef struct List_node
{
int data;
struct List_node *next;
struct List_node *prev;
}List_node;
typedef struct List
{
List_node *head;
}List;
List *create_list()
{
List *list = (List*) malloc(sizeof(List));
list->head = NULL;
return list;
}
int List_size(List *list)
{
List_node *p;
int counter = 0;
p = list->head;
while (p != NULL)
{
p = p->next;
counter = counter + 1;
}
return counter;
}
void insert_first(List_node *x, List *list)
{
x->next = list->head;
list->head = x;
}
void insert(List_node *x, List_node *y)
{
x->next = y->next;
y->next = x;
}
/* my own additions */
List_node *mk_node(int data) {
List_node *node = (List_node *) malloc(sizeof(List_node));
node->data = data;
return node;
}
void delete_list(List *list) {
List_node *node = list->head;
while (node != NULL) {
List_node *next = node ->next;
free(node);
node = next;
}
free(list);
}
int main() {
List* list = create_list();
List_node *node, *next;
int i;
node = mk_node(0);
insert_first(node, list);
for (i=1; i<5; i++) {
next = mk_node(i);
insert(next, node);
node = next;
}
int n = List_size(list);
printf("size : %d\n", n);
node = list->head;
while (node != NULL) {
printf("node val : %d\n", node->data);
node = node->next;
}
delete_list(list);
return 0;
}
(*) Your code is not perfect because List_node struct contains a pointer prev that is never used, so you end with a single-linked list with every third value unused.
I added a comment above that I copied your code into my compiler and that it doesn't compile, so it won't run: the calls to create_list don't compile: they return a value as function return, not in a parameter; there are undeclared variables. Further, it is useless to give create_list and mk_node a parameter: they will allocate an array, not create a single list element. A call of calloc(1, sizeof(your_thing)) would suffice. After fixing these erors, several bugs became apparent:
in insert_first(node, &L2); you give it the address of the list, which is already a pointer. Remove the '&' (the compiler should have complained!).
same for List_size(&L1); L1 is already a pointer. Remove the '&'.
in: if (x <= y ...) you compare memory addresses. Change to: if (x->data <= y->data...)
in that statement the part "x->next >= y" also compares memory address, and I don't see why it is needed. I removed it.
The real problem seems to be in merge. You should either merge the lists into L1, or into L2, and preferably should create a result list. But you "randomly" insert an element into L1, then into L2, then again into L1, etcetera. In my test it ran indefinitly. The following merge works fine:
List *merge(List *small_list, List *big_list)
{
List_node *x, *y, *r;
List *result= create_list();
y = small_list->head;
x = big_list->head;
if (x->data < y->data)
{result->head= x; x= x->next;}
else {result->head= y; y= y->next;}
r= result->head;
while (y != NULL && x != NULL)
{
if (x->data < y->data)
{
r->next= x;
x = x->next;
}
else {
r->next= y;
y = y->next;
}
r= r->next;
}
while (y != NULL)
{
r->next= y;
y = y->next;
r= r->next;
}
while (x != NULL)
{
r->next= x;
x = x->next;
r= r->next;
}
r->next= 0;
return (result);
}
So the problem is that you allocate the list head, but never allocate memory for the list elements. Serge added mk_node which does the allocation (so Serge solved it).
Related
currently i'm trying out some algorithms. The Bubblesort with swapping the data works fine, but when i try to use the swap adress function the program ends with an error. I hope someone can help me
The structure i use is:
struct Node_s{
int data;
struct Node_s *next;
};
typedef struct Node_s Node_t;
Thats my function to swap the nodes:
Node_t* swap_adr(Node_t *ptr1, Node_t *ptr2)
{
Node_t *temp;
temp=ptr2->next;
ptr2->next=ptr1;
ptr1->next=temp;
return ptr2;
}
Thats the function which calculates the length of the list:
int len(Node_t* head)
{
Node_t* temp = head ;
int i = 0 ;
while(temp!=NULL)
{
i++;
temp=temp->next ;
}
return i ;
}
Thats the BubbleSort funciton which does not work:
void bubbleSort(Node_t* head)
{
int length=len(head);
Node_t* temp;
int i, j, swapped;
Node_t* p1,*p2;
for(i=0;i<=length;i++)
{
temp = head;
swapped = 0;
for (j = 0; j < length - 1; j++)
{
p1 = temp;
p2 = p1->next;
if (p1->data > p2->data)
{
/* update the link after swapping */
temp = swap_adr(p1, p2);
swapped = 1;
}
temp = temp->next;
}
}
}
The strange thing is, this code works, i don't understand why?
void bubbleSort(Node** head)
{
int length=len(*head);
Node** temp;
int i, j, swapped;
Node* p1,p2;
for (i = 0; i <= length; i++)
{
temp = head;
swapped = 0;
for (j = 0; j < length - i - 1; j++)
{
p1 = *temp;
p2 = p1->next;
if (p1->data > p2->data)
{
/* update the link after swapping */
*temp = swap(p1, p2);
swapped = 1;
}
temp = &(*temp)->next;
}
if (swapped == 0)
break;
}
return;
}
You need an extra variable for the previous node (i.e. the one before p1).
When you swap the next pointers in the loop, you have to change prev->next from p1 to p2
Here is some refactored code. It is annotated. I've compiled it but not tested it:
#include <stdio.h>
typedef struct node {
int data;
struct node *next;
} Node_t;
void
bubbleSort(Node_t *head)
{
Node_t *temp;
Node_t *rhs;
Node_t *lhs;
Node_t *prev;
// get list total length
int length = 0;
for (temp = head; temp != NULL; temp = temp->next)
++length;
// reduce length by one on each pass (the last element on each pass is
// correct -- no need to rescan)
for (; length > 1; --length) {
int swapped = 0;
// get the two pointers
rhs = NULL;
lhs = head;
if (lhs != NULL)
rhs = lhs->next;
prev = NULL;
int i = 1;
for (; rhs != NULL; prev = lhs, lhs = rhs, rhs = rhs->next, ++i) {
// no need to traverse the entire list on subsequent passes
if (i >= length)
break;
// nodes are in sort
if (lhs->data <= rhs->data)
continue;
// swap the node pointers
temp = lhs->next;
lhs->next = rhs->next;
rhs->next = temp;
// link previous node to new lhs (i.e. rhs)
if (prev != NULL)
prev->next = rhs;
// new list head
else
head = rhs;
// swap lhs/rhs so that the for loop works
temp = lhs;
lhs = rhs;
rhs = temp;
// say a swap was done
swapped = 1;
}
// early escape if no swap
if (! swapped)
break;
}
}
If you want to swap addresses, then you have to pass the addresses of the two elements you want to swap.
For example, if you want to swap pointers, which are basically addresses, then you have to pass the addresses of the addresses. Thus:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
void node_swap(struct node **p, struct node **q) // Pass the address of (struct node*)
{
struct node *tmp = *p;
*p = *q;
*q = tmp;
}
int main(void)
{
struct node *n1 = malloc(sizeof *n1);
struct node *n2 = malloc(sizeof *n2);
n1->data = 1;
n2->data = 2;
printf("N1 = %d\n", n1->data);
printf("N2 = %d\n", n2->data);
node_swap(n1, n2);
printf("N1 = %d\n", n1->data);
printf("N2 = %d\n", n2->data);
free(n1);
free(n2);
}
Output:
N1 = 1
N2 = 2
N1 = 2
N2 = 1
EDIT You probably should avoid typedefing your structs. But in case you insist on that, here's how your code should look like:
struct node {
int data;
struct node *next;
};
typedef struct node node_s;
typedef struct node *node_ptr;
void node_swap(node_ptr *p, node_ptr *q) // Pass the address of p and q
{
node_ptr tmp = *p;
*p = *q;
*q = tmp;
}
I'm basically trying to implement LinkedList in C but I still can't get it I will leave my code below so you can see what I'm missing:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int val;
struct Node *Next;
};
struct Node *head;
void insert(int x);
void print();
int main() {
head = NULL;
int d, i = 0, f;
printf("How many number you want to insert:\n");
scanf("%d", &d);
for (i; i < d; i++) {
printf("Enter your number:\n");
scanf("%d", &f);
insert(f);
print();
}
return 0;
}
void insert(int x) {
struct Node *A = (struct Node *)malloc(sizeof(struct Node));
if (head == NULL) {
A->val = x;
A->Next = head;
head = A;
return;
}
A->val = x;
A->Next = head->Next;
}
void print() {
printf("[");
struct Node *B = head;
while (B->Next != NULL) {
B = B->Next;
printf("%d", B->val);
}
printf("]\n");
}
I need some pointers to where I missed up.
Here are the two ways to insert, either at the front/head of the list or the back/tail of the list:
void
insert_front(int x)
{
struct Node *A = malloc(sizeof(*A));
A->val = x;
A->Next = head;
head = A;
}
void
insert_back(int x)
{
struct Node *A = malloc(sizeof(*A));
A->val = x;
A->Next = NULL;
struct Node *prev = NULL;
for (struct Node *cur = head; cur != NULL; cur = cur->Next)
prev = cur;
if (prev != NULL)
prev->Next = A;
else
head = A;
}
The print() function is incorrect: it misses the first node and would crash on an empty list:
void print() {
printf("[");
struct Node *B = head;
while (B != NULL) {
printf(" %d", B->val);
B = B->Next;
}
printf(" ]\n");
}
The insert() function also has problems: only the first node is correctly inserted. Here is a modified version:
// insert a node in front of the list.
void insert(int x) {
struct Node *A = (struct Node *)malloc(sizeof(struct Node));
if (A != NULL) {
A->val = x;
A->Next = head;
head = A;
}
}
can any one tell me where is the error in this program please it will be really helpful , i did my best to solve this problem ,this code is passing only two test cases
Given an undirected graph and a starting node, determine the lengths of the shortest paths from the starting node to all other nodes in the graph. If a node is unreachable, its distance is -1. Nodes will be numbered consecutively from to , and edges will have varying distances or lengths.
Here is the question https://www.hackerrank.com/challenges/dijkstrashortreach/problem
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
// Node
typedef struct node {
int data;
// Lower values indicate higher priority
int priority;
struct node* next;
} Node;
// Function to Create A New Node
Node* newNode(int d, int p)
{
Node* temp = (Node*)malloc(sizeof(Node));
temp->data = d;
temp->priority = p;
temp->next = NULL;
return temp;
}
// Return the value at head
int peek(Node** head)
{
return (*head)->data;
}
// Removes the element with the
// highest priority form the list
void pop(Node** head)
{
Node* temp = *head;
(*head) = (*head)->next;
free(temp);
}
void updateprt(Node** head, int data) {
if ((*head)->data == data)
{
Node* temp = *head;
*head = (*head)->next;
free(temp);
return;
}
Node* prev = *head;
while ((prev->next)->data != data) {
prev = prev->next;
}
Node* start = prev->next;
prev->next = start->next;
free(start);
}
// Function to push according to priority
void push(Node** head, int d, int p)
{
Node* start = (*head);
// Create new Node
Node* temp = newNode(d, p);
if (*head == NULL) {
*head = temp;
return;
}
// Special Case: The head of list has lesser
// priority than new node. So insert new
// node before head node and change head node.
if ((*head)->priority > p) {
// Insert New Node before head
temp->next = *head;
(*head) = temp;
}
else {
// Traverse the list and find a
// position to insert new node
while (start->next != NULL &&
start->next->priority < p) {
start = start->next;
}
// Either at the ends of the list
// or at required position
temp->next = start->next;
start->next = temp;
}
}
// Function to check is list is empty
int isEmpty(Node** head)
{
return (*head) == NULL;
}
struct adjlistnode {
int data;
struct adjlistnode* next;
};
struct adjlist {
struct adjlistnode* head;
};
struct graph {
int v;
struct adjlist* array;
};
struct graph* creategraph(int v) {
struct graph* G = (struct graph*) malloc(sizeof(struct graph));
G->v = v;
int i;
G->array = (struct adjlist*)malloc(sizeof(struct adjlist)*v);
for (i = 0; i < v; i++) {
G->array[i].head = NULL;
}
return G;
}
int Distance[100000], path[50];
struct adjlistnode* getnewnode(int ver) {
struct adjlistnode* newnode = (struct adjlistnode*)malloc(sizeof(struct adjlistnode));
newnode->data = ver;
newnode->next = NULL;
return newnode;
}
void addedge(struct graph* G, int src, int dest, long int w, long int** weight) {
struct adjlistnode* temp;
temp = getnewnode(dest);
temp->next = G->array[src].head;
G->array[src].head = temp;
temp = getnewnode(src);
temp->next = G->array[dest].head;
G->array[dest].head = temp;
if (weight[src][dest] != 0 || weight[dest][src] != 0 && w < weight[src][dest]) {
weight[src][dest] = w;
weight[dest][src] = w;
}
if (weight[src][dest] == 0) {
weight[src][dest] = w;
weight[dest][src] = w;
}
}
void printgraph(struct graph* G) {
for (int i = 0; i < G->v; i++) {
struct adjlistnode* temp = G->array[i].head;
printf("%d-> ", i);
while (temp) {
printf(" %d", temp->data);
temp = temp->next;
}
printf("\n");
}
}
void Dijkstra(Node** queue, struct graph* G, int s, long int** weight) {
int v, w, d;
push(queue, s, 0);
for (int i = 0; i < 100000; i++) {
Distance[i] = -1;
}
Distance[s] = 0;
while (!isEmpty(queue)) {
v = peek(queue);
pop(queue);
struct adjlistnode* temp = G->array[v].head;
while (temp) {
w = temp->data;
d = Distance[v] + weight[v][w];
//To update the distance of w check the below two conditions
if (Distance[w] == -1) {
Distance[w] = d;
push(queue, w, d);
path[w] = v;
}
if (Distance[w] > d)
{
Distance[w] = d;
path[w] = v;
updateprt(queue, w);
push(queue, w, d);
}
temp = temp->next;
}
}
}
int main()
{
int t;
scanf("%d", &t);
while (t) {
Node* pq = NULL;
int v;
int e;
scanf("%d %d", &v, &e);
long int** weight = (long int**)malloc(sizeof(long int*)*v);
for (int i = 0; i < v; i++)
weight[i] = (long int*)malloc(sizeof(long int)*v);
struct graph* G = creategraph(v);
int u, w;
long int l;
for (int i = 0; i < e; i++) {
scanf("%d %d %ld", &u, &w, &l);
addedge(G, u - 1, w - 1, l, weight);
}
int s;
scanf("%d", &s);
// printgraph(G);
//printf("\n");
Dijkstra(&pq, G, s - 1, weight);
for (int i = 0; i < G->v; i++) {
if (i == s - 1)
continue;
printf("%d ", Distance[i]);
}
/* while (!isEmpty(&pq)) {
printf("%d ", peek(&pq));
pop(&pq);
}*/
return 0;
}
system("pause");
}
Your biggest issue is with your priority queue, which you implement as simple linked list. You seem to be confused about when and how to use a pointer to node pointer.
For example, this function:
int isEmpty(Node **head) ...
only inspects the list. It doesn't modify it, so it is enough to pass a node pointer:
int isEmpty(Node *head) ...
This function doesn't modify the contents of the nodes, either, so this could be made explicit:
int isEmpty(const Node *head) ...
On the other hand, the push, pop and updateprt functions must be able to change the head via a pointer, so they require a pointer to a node pointer. Your pop function, which always changes the head, does this. The other functions look like this:
void push(Node** head, int d, int p)
{
Node* start = (*head);
// ... do stuff with start, leave head alone ...
}
Here, you have just used the pointer to node pointer as an overly obscure way to pass in information about the head, but you never modify it (except in the special case of inserting into an ampty list).
Here's how that push function should look like:
void push(Node **head, int d, int p)
{
Node *temp = newNode(d, p);
while (*head && (*head)->priority < p) {
head = &(*head)->next;
}
temp->next = *head;
*head = temp;
}
Note how there aren't any special cases. When you call push(&queue, ...), you pass the address of the head pointer and you can modify the local variable queue in the calling function by assigning to *head. When you walk through the list with head = &(*head)->next, head holds the address of the next field of the previous node, which you can also modify via *head. The pointer to a pointer adds one level of indirection and tells you where you have come from and lets you modify that value.
In the same vein, you can change (and simplify) your updateptr function:
void updateprt(Node** head, int data)
{
while (*head && (*head)->data != data) {
head = &(*head)->next;
}
if (*head) pop(head);
}
With these changes, your program should work, but there are other things to note:
if (weight[src][dest] != 0 || weight[dest][src] != 0 && w < weight[src][dest]) ...
The condition (w1 == 0 || w2 == 0 && w < w1) is parsed as (w1 == 0 || (w2 == 0 && w < w1)), which probably isn't what you want. The check for zero is ot done correctly, because you never initialize weight. (You could use calloc instead of malloc to create a zero-initialized array.)`
But why have a separate array of weights at all? You could store the weight with each edge:
struct adjlistnode {
int data; // destination vertex
int weight;
struct adjlistnode* next;
};
The same goes for the arrays:
int Distance[100000], path[50];
Both arrays provide one entry for each vertex. The first one is too generous ("I'll allocate a bit more, just in case ..."), the second could be too small. (You don't need the path for the task, but it's always nice to be able to verify it. The variable isn't a path, however, it holds the next step towards the starting point for each vertex.)
The competition rules say that there are at most 3,000 nodes, so you could just dimension your arrays with [3000], but you cold also make them part of the graph structure and allocate according to the number of vertices.
Good luck!
The question I came across.
Here is what I have done so far
#include <stdio.h>
#include <stdlib.h>
struct node
{
int digit;
struct node *next;
};
struct node *make_node(int num, struct node *head);
struct node *newNode(int digit);
struct node *sum(struct node *num1, struct node *num2);
void print(struct node *node);
int main()
{
int a, b;
struct node *new_nodeA1 = NULL, *new_nodeA2 = NULL;
struct node *new_nodeB1 = NULL, *new_nodeB2 = NULL;
struct node *res = NULL;
printf("\nEnter no. of digits for your two numbers (separate with space) ");
scanf("%d %d", &a, &b);
int n1[a], n2[b];
printf("\n\nEnter first non-negative integer to add: ");
for (int j = 0; j < a; j++)
scanf("%1d", &n1[j]);
printf("Enter second non-negative integer to add: ");
for (int k = 0; k < b; k++)
scanf("%1d", &n2[k]);
/* for (int i = 0; i <= a - 1; i++)
printf("%d\n", n1[i]);
printf("%d\n", a); */
for (int z = 0; z < a - 1; z++)
{
new_nodeA2 = make_node(n1[z], new_nodeA1);
/*new_nodeA2 = newNode(n1[z]);*/
if (new_nodeA1 == NULL)
new_nodeA1 = new_nodeA2;
}
for (int y = 0; y < b - 1; y++)
{
new_nodeB2 = make_node(n2[y], new_nodeB1);
if (new_nodeB1 == NULL)
new_nodeB1 = new_nodeB2;
}
printf("\n");
print(new_nodeA1);
printf("\n");
print(new_nodeB1);
printf("\n")
res = sum(new_nodeA2, new_nodeB2);
printf("Result: ");
print(res);
return 0;
}
struct node *make_node(int num, struct node *head)
{
struct node *temp = malloc(sizeof(struct node));
if (temp == NULL)
{
fprintf(stderr, "Call of malloc() failed\n");
exit(1);
}
if (head != NULL)
head->next = temp;
temp->digit = num;
temp->next = NULL;
return temp;
}
struct node *newNode(int digit)
{
struct node *new_node = (struct node *) malloc(sizeof(struct node));
new_node->digit = digit;
new_node->next = NULL;
return new_node;
}
struct node *sum(struct node *num1, struct node *num2)
{
struct node *res = NULL;
struct node *temp, *prev = NULL;
int carry = 0, sum;
while (num1 != NULL || num2 != NULL)
{
sum = carry + (num1? num1->digit: 0) + (num2? num2->digit: 0);
carry = (sum >= 10)? 1 : 0;
sum = sum % 10;
temp = newNode(sum);
if(res == NULL)
res = temp;
else
prev->next = temp;
prev = temp;
if (num1)
num1 = num1->next;
if (num2)
num2 = num2->next;
}
if (carry > 0)
temp->next = newNode(carry);
return res;
}
void print(struct node *node)
{
while(node != NULL)
{
printf("%d->", node->digit);
node = node->next;
}
printf("\n");
}
My Output
My compiler does not give me any error. I tried debugging my make_node function but I cant catch the problem as to why my nodes are skipping certain digits.
Your linked list insert code is very broken. For this style of list, you need to walk down the list from head->next until a null is found and insert there. Instead, you are always replacing the head->next with your new temp node, thus breaking the list.
You can also add to the list backwards, making the newly added item the head each time and thus get around the traversal for add, but beware this will place your numbers in reverse order (which actually helps when you do your adding, so perhaps this is good too.)
typedef struct record
{
char name[20];
char surname[20];
char telephone[20];
}Record;
typedef struct node
{
Record data;
struct node *next;
}Node;
Node *head = NULL;
/*
return positive value if *x > *y
return negative value if *x < *y
return 0 if *x == *y
*/
int cmpRecord(const Record* x, const Record* y) {
if (x->name > y->name) return 1;
if (x->name < y->name) return -1;
return 0;
}
void addRecord(Record x)
{
Node *previousNode = NULL;
Node *newNode;
Node *n;
newNode = (Node*)malloc(sizeof(Node));
newNode->data = x;
newNode->next = NULL;
if (head == NULL) // The list is empty
{
head = newNode;
}
else // The list is not empty
{
n = head;
while (n->next != NULL)
{
if ((cmpRecord(&n->data.name, &newNode->data.name) < 0) && (cmpRecord(&n->next->data.name, &newNode->data.name) > 0)) // Insertion Sort
{
// We have to put it between these 2 nodes
newNode->next = n->next;
n->next = newNode;
return;
}
else
{
previousNode = n;
n = n->next;
}
}
n->next = newNode;
}
}
So this code is supposed to add records of people in a list and sort them alphabetically according to the Name. However when displaying the list, the items are not in alphabetical order. What seems to be the problem? Thanks
PS. The cmpRecord is used in the if-statement for the insertion sort.
To compare two string alphabetically, use strcmp():
int cmpRecord(const Record* x, const Record* y) {
int cmp = strcmp(x->name, y->name);
return (cmp > 0) - (cmp < 0);
}
and call this function by cmpRecord(&n->data, &newNode->data);, because the data field has type Record.