i tried to create linked list as follows but the output comes a fixed list
of two elements and count to be 2
#include<stdio.h>
#define null 0
struct list
{
int num;
struct list *next;
};
typedef struct list node;
int create(node *list)
{ int n;
printf("enter the element to end the list finish it with -999\n");
scanf("%d",&n);
if(n==-999)return 0;
else {
list=(node *)malloc(sizeof(node *));
list->num=n;
if(!(create(list->next)))list->next=null;
return 1}
}
void printlist(node * list) {
if(list->next==null)
{printf("%d->",list->num);return;}
else
{printf("%d->",list->num);printlist(list->next);}
return;
}
int count(node *list) {
if(list->next==null)return 1;
else return(1+count(list->next));
}
void main() {
node *list;
create(list);
printlist(list);
printf("\n%d",count(list));
}
is there any problem with passing pointer to the function.
When you pass in a pointer to create it creates a copy of the pointer. That is, if you modify list in create it will not change the value of list in main.
Try passing in the pointer to list in main to create. This will allow you to cange list inside create.
// in main:
create(&list)
// in create
int create(node** listptr) {
// similar code to before except
// that list should be replaced with
// (*listptr)
//
// the example below will assing a value
// to the variable list in main:
// (*listptr) = x
// ...
}
Print should work as is. It doesn't need a node** as it won't change the list.
Related
Let "List" be a struct that represents a singly-linked list, i have the following function:
int List_contains(List node, const char* key) {
List *search;
search=node.next;
assert(search->key!=NULL);
return 1;
}
and List is the following struct:
typedef struct List { /*A new node*/
char* key;
void* value;
struct List *next;
} List;
The function "List_contains" should tell me if "key" is contained in the list or not. Problem is, i can't iterate through the list, and the line
assert(search->key != NULL);
throws a Segfault. How can i iterate through the list with what i have?
(Note: The function is, obviously, not "completed".)
Here is an example of a search I wrote a while back.
struct node
{
int data;
struct node *next;
};
int
search_list(struct node *head, int search)
{
if (!head)
{
fprintf(stderr, "Invalid head\n");
return 1;
}
struct node *temp = head;
while (temp)
{
if (temp->data == search)
{
printf("Found %d\n", search);
break;
}
temp = temp->next;
}
return 0;
}
int List_contains(List node, const char* key) {
List *search;
search=node.next;
assert(search->key!=NULL);
return 1;
}
so a lot to parse here...
Generally you would pass in a pointer to the node so that it isn't copied, but it is actually safe to do what you have done, in this instance, assuming no multithreaded shenanigans go on...
but in the future I would look for:
int List_contains(List* node, const char* key) {
next line you make a pointer without a value... which is fine, because you assign it the next line, but that could be condensed...
// List *search;
// search=node.next; # could easily become:
List *search = node.next;
now at this point you actually know if you are at the end of the list...
if(search == null)
{
return 0;
}
after that you need to do some sort of compare...
if (strcmp(key,search->key) == 0)
{
//found it;
return 1;
}
now you have code that will match the key against the first element of the list, so you would need to put the whole thing in a loop, each iteration swapping search with search->next and checking for null
I am trying to create a dynamic array of players which I can add to during run time - however if I create 3 players with x-coords: 4,7 and 15, then try to print these values the output is: 0, 33, 20762704.
I am new to C and pointers and am struggling to work out where it is going wrong.
#include <stdio.h>
#include <stdlib.h>
// contains data of a player
struct player {
int posX;
int posY;
int gold;
};
// struct for creating a list of players of dynamic size
struct playerList {
struct player p;
struct playerList *next;
};
// add a new player to the list with given coords
struct playerList *make(int x, int y) {
struct playerList *new_player;
new_player = (struct playerList *)malloc(sizeof(struct playerList));
new_player->p.posX = x;
new_player->p.posY = y;
new_player->p.gold = 0;
new_player->next = NULL;
return new_player;
}
// add a player to the list
void addPlayer(struct playerList *list, int x, int y) {
if(list->next) {
addPlayer(list->next,x,y);
}
else {
list->next = make(x,y);
}}
int main() {
struct playerList *players = (struct playerList *)malloc(sizeof(struct playerList));
addPlayer(players, 4,3);
addPlayer(players, 7,7);
addPlayer(players,15,1);
printf("%d\n",players[0].p.posX);
printf("%d\n",players[1].p.posX);
printf("%d\n",players[2].p.posX);
return 0;
}
In order to add the first player to the list, you must pass a pointer-to-pointer-to-playerList to addPerson because the first node address will become the list address. Otherwise, you must return type *playerList and assign the return to your list variable back in the calling function. It is just as easy to pass the playerList ** parameter to your function and return a pointer to indicate success/failure as well as for convenience. e.g.:
/* add a player to the list */
playerList addPlayer (struct playerList **list, int x, int y) {
struct playerList *node = make (x, y);
if (!node) { /* validate new player created */
fprintf (stderr, "error: make player failed for (%d,%d).\n", x, y);
return NULL;
}
if (!*list) /* if first node, set list address to node & return */
return *list = node;
struct playerList *iter = *list; /* list pointer to iterate to end */
/* insert all other nodes at end */
for (; iter->next; iter = iter->next) {}
iter->next = node; /* add new player at end, return original *list */
return *list;
}
Then in main
addPlayer(&players, 4,3);
...
(note: the addPlayer is no longer recursive. As your list size grows, the additional resources needed for recursive calls can become significant, further, there is no need for a recursive call as the procedural iteration to the end of list to add a new player is straight forward.)
Look over the change and let me know if you have any additional questions. (note: I have not checked the remainder of your code for further errors)
In the list, you have a node that you are going to save some data on it, and it points to the next node too. So, you could define list structure to maintain the head of your list, and probably some other required information such length of the list or garbage handling or ...
For initialization you should set the length with zero and head pointer of list to NULL, these steps show the empty status of the list.
When you want to add to the list, you could add at the end of it, or at the head of it. In your program, you choose the second insertion policy, at the end. So, to add, you should traverse the list (all nodes), to find the last node, to add new node after that one. You should be aware of adding the new node when the list is empty, in this case you should update the head of your list.
For printing, there is a similar way, you should traverse the list and print the node information of that, until you reach the null pointer at the end of list.
After any allocation you should check the allocation success, if the pointer is not null, it was successful.
Another point, when you can handle adding the new node with using a simple loop, why you should use the recursive function? In this cases, it is better to use the loop.
The last point, dynamic allocation memory used commonly when the number of the list is specified in the run time, for example. It is a good point, to less memory allocation if you don't have to use. For instance, in the main you could define the list variable as a static variable, and send the address of that to the functions.
I tested the program, and its output was okay.
#include <stdio.h>
#include <stdlib.h>
// contains data of a player
struct player {
int posX;
int posY;
int gold;
};
// struct for creating a list of players of dynamic size
struct playerNode {
struct player p;
struct playerNode *next;
};
struct playerList {
struct playerNode *head;
int len;
// Add other required variables here
};
// add a new player to the list with given coords
struct playerNode *make(int x, int y) {
struct playerNode *new_player;
// you need to check memory allocation success
new_player = malloc(sizeof(struct playerNode));
new_player->p.posX = x;
new_player->p.posY = y;
new_player->p.gold = 0;
new_player->next = NULL;
return new_player;
}
// add a player to the list
void addPlayer(struct playerList *list, int x, int y) {
struct playerNode *player = list->head;
if(!player)
// you need to check memory allocation success
list->head = make(x, y);
else
{
while (player->next) {
player = player->next;
}
// you need to check memory allocation success
player->next = make(x, y);
}
list->len++;
}
void showPlayers(struct playerList *list) {
struct playerNode *player = list->head;
while (player) {
printf("%d\n", player->p.posX);
printf("%d\n", player->p.posY);
printf("%d\n", player->p.gold);
printf("--------------------\n");
player = player->next;
}
}
int main() {
struct playerList players;
players.len = 0;
players.head = NULL;
addPlayer(&players, 4, 3);
addPlayer(&players, 7, 7);
addPlayer(&players, 15, 1);
showPlayers(&players);
return 0;
}
Is there any general user defined function that can be used to sort any given linked list, given that it has a pointer field and a data field.
The function should not swap the data between the nodes. The swapping should be done by using the pointers.
I found one online, but it is using a user defined function. I'm not allowed to use any other functions, but the bubble sort one.
We were asked not to initialize any new variables, other than temp structs within the function. So, i can't use integers or variables like swapped.
The one that i was using is as follows:
/* Bubble sort the given linked lsit */
void bubbleSort(struct node *start)
{
int swapped, i;
struct node *ptr1;
struct node *lptr = NULL;
/* Checking for empty list */
if (ptr1 == NULL)
return;
do
{
swapped = 0;
ptr1 = start;
while (ptr1->next != lptr)
{
if (ptr1->data > ptr1->next->data)
{
swap(ptr1, ptr1->next);
swapped = 1;
}
ptr1 = ptr1->next;
}
lptr = ptr1;
}
while (swapped);
}
/* function to swap data of two nodes a and b*/
void swap(struct node *a, struct node *b)
{
int temp = a->data;
a->data = b->data;
b->data = temp;
}
Given that my linked list structure is as follows:
struct node
{
int data;
struct node *next;
};
For your case, you can use an edited version of the function that you have provided. The swap function was omitted in here.
//Sorting according to the data, ascending order
void bubbleSortLL(struct node *header){
struct node *temp1, *temp2, *temp3, *temp4, *temp5;
temp4=NULL;
while(temp4!=header->next)
{
temp3=temp1=header;
temp2=temp1->next;
while(temp1!=temp4)
{
if(temp1->data > temp2->data)
{
if(temp1==header)
{
temp5=temp2->next;
temp2->next=temp1;
temp1->next=temp5;
header=temp2;
temp3=temp2;
}
else
{
temp5=temp2->next;
temp2->next=temp1;
temp1->next=temp5;
temp3->next=temp2;
temp3=temp2;
}
}
else
{
temp3=temp1;
temp1=temp1->next;
}
temp2=temp1->next;
if(temp2==temp4)
temp4=temp1;
}
}
}
This will work by passing your specified list as an argument. Nevertheless, i don't understand why you can't use the swap function.
To get rid of the call of the swap function, replace the
function call with its content:
Instead of
swap(ptr1, ptr1->next);
write
int temp = ptr1->data;
ptr1->data = ptr1->next->data;
ptr1->next->data = temp;
To swap the elements and not the data, you need
to to track the previous element.
Here a suggestion for the swap of the elements(without maybe needed NULL checks)
previous->next = ptr1->next;
previous->next->next=ptr1;
Instead of ptr1=ptr1->next you need:
previous=previous->next;
ptr1=previous->next;
I am trying to write a function that takes in as an argument a linked list of structs. One of the elements of these structs is a value for storing the position, example struct #3 has 3 for the element. The list that comes in is not in order. I want to go through each element in the linked list and set the value based on the order they are in. How would I do this?
nodeT numberStructs(nodeT *temp)
{
int i;
i=0;
while(temp!=NULL)
{
temp->struct.struct_order=i;
temp=temp->next;
i++;
}
return temp;
}
This is clearly not going to cut it but it's what I got so far.
Also, to clarify, I will be adding elements, moving elements, deleting elements etc. Instead of adjusting the counts every time do something that changes the line order, I want to call a single function to straighten these out. This allows me to just change the pointers of the linked list structs whenever I want to make a change.
typedef struct NodeT {
struct Node *next;
int struct_order;
...
} NodeT;
void fill_idx(NodeT *first) {
int idx;
NodeT *node;
for (node = first, idx = 0;
node;
node = node->next, ++idx) {
node->struct_order = idx;
}
}
Equivalently, with a while loop:
void fill_idx(NodeT *first) {
int idx = 0;
NodeT *node = first;
while (node) {
node->struct_order = idx;
node = node->next;
++idx;
}
}
int search( struct node **front, int val)
{
struct node *cur;
cur=*front;
while(cur!=NULL)
{
cur=cur->next;
}
return cur!=NULL;
}
This will always run to the end of the list, then return 0, so no. You need to compare with val somewhere.
Also, passing front as a struct node ** is not necessary, since you're never assigning *front. Pass it as a const struct node * instead.
Your code is equivalent to
int search(struct node **front, int val)
{
return 0;
}
except that it will crash and burn if it is passed a NULL first argument.
No. Nowhere in your logic you are making use of val. Try this -
int search( struct node *front, int val)
{
while(front != NULL)
{
if( front->val == val ) // Assuming struct node has val member which you are trying to compare to
return 1; // found it
front=front->next;
}
return 0; // Not found
}
Where is the comparison to the variable val being made ?
The code can not check whether a node with value "val" is present in the linked list.