i have a single list non-circular without sentinel and i want to duplicate every node of it. For example, i have 7,5,12,16 and i want to have : 7,7,5,5,12,12,16,16 but i can't create it.Below is my function code for duplicate the nodes(other parts of the program are correct).
int duplicate_list(listT *list_head) {
listT *current, *new_node;
for(current = list_head; current != NULL; current = current->next,counter++) {
new_node = (listT *)malloc(sizeof(listT));
if(new_node == NULL) {
printf("problem in new_node\n");
free(new_node);
exit(-1);
}
new_node->data = current->data;
new_node->next = current;
}
return(1);
}
Can someone help me?
You are not inserting duplicate new_node in the list, you are just creating the new nodes in loop. Consider below example for your reference.
int duplicate_list(listT *list_head) {
listT *current, *new_node;
for(current = list_head; current != NULL; current = current->next,counter++) {
new_node = malloc(sizeof(*new_node));
if(new_node == NULL) {
perror("problem in new_node");
exit(1);
}
new_node->data = current->data;
new_node->next = current->next;
current->next = new_node;
current = new_node;
}
return(1);
}
Related
So I encounter this problem where when I add nodes to an empty head in a specific sequence it doesn't work.
If I insert 2,1,3,4 so the second number is smaller than the first number, then it works. But if I add 2,3,4,5, then it doesn't work. I get a Segmentation fault (core dumped).
Can somebody tell me whats wrong here?
This is my struct and adding-method:
struct list_node{
int value;
struct list_node* next;
};
typedef struct list_node node_t;
node_t* add_element_sorted(node_t* head, int v){
node_t* current = head;
node_t* new = NULL;
new = (node_t *) malloc (sizeof(node_t));
if (new == NULL) {
printf("error");
exit(1);
}
new->value = v;
printf("%d\n", new->value);
if (current != NULL){ //check if first node is empty
while(current->value < v){
current = current->next;
printf("broke \n");
if(current->next == NULL){ // check if current node is the last then its next shoud be null
break;
}
}
}
if (current == head) {
new->next = head;
return new;
} else {
new->next = current->next;
current->next = new;
return head;
}
}
At this part it returns me current->next is neither NULL or !NULL. What is current->next now?
if(current->next == NULL){ // check if current node is the last then its next shoud be null
break;
}
My main looks like this:
int main(){
node_t* head = NULL;
head = add_element_sorted(head, 2);
head = add_element_sorted(head, 3);
head = add_element_sorted(head, 4);
head = add_element_sorted(head, 5);
return 0;
}
I try to implement the delete method but that doesn't work with me. I want to delete all nodes in the tree. The function has tree type of "struct tree" as a parameter so I can't use recursion; I want to do it with a loop.
That's my structure
typedef struct Node Node;
struct Node{
const void* data;
const void* value;
Node* left;
Node* right;
};
typedef struct Tree Tree;
struct Tree{
Node* root;
size_t size;
int (*comp)(const void *, const void *);
};
function delete
void freeTree(Tree* tree, bool TreeContent){
if(tree->root != NULL){
// free(tree->root->left);
// free(tree->root->right);
// free(tree->root);
}
}
function insert
bool insertInTree(Tree* bst, const void* key, const void* value){
if(bst->root == NULL){
Node* newNode = (Node*) malloc(sizeof(Node));
if(newNode == NULL){
printf("erreur d'allocation dynamique \n");
exit(1);
}
newNode->left = newNode->right = NULL;
newNode->value = value;
newNode->data = key;
return true;
}
else{
int isLeft = 0 ;
Node* Current = bst->root ;
Node* precedant = NULL;
while(Current != NULL){
int compare = bst->comp(&Current->data , &key);
precedant = Current;
if(compare == 1){
isLeft = 1;
Current = Current->left;
}
else if(compare == 0){
isLeft = 0;
Current = Current->right;
}
}
if(isLeft == 1){
Node* newNode = (Node*) malloc(sizeof(Node));
if(newNode == NULL){
printf("erreur d'allocation dynamique \n");
exit(1);
}
newNode->left = newNode->right = NULL;
newNode->value = value;
newNode->data = key;
precedant->left = newNode;
bst->size++;
return true;
}
else{
Node* newNode = (Node*) malloc(sizeof(Node));
if(newNode == NULL){
printf("erreur d'allocation dynamique \n");
exit(1);
}
newNode->left = newNode->right = NULL;
newNode->value = value;
newNode->data = key;
precedant->right = newNode;
bst->size++;
return true;
}
}
return false;
}
edit You don't want to use recursion because the freeTree function doesn't take a Node argument. In this case, you can remove that restriction by creating another function that is recursive, called initially by freeTree.
void freeTree(Tree* tree, bool TreeContent){
if(tree->root != NULL){
freeNode(tree->root);
tree->root = NULL;
}
}
The new freeNode could look like
void freeNode(Node *node) {
if (node->left) freeNode(node->left);
if (node->right) freeNode(node->right);
free(node);
}
Note that freeNode intent is to free the whole tree (otherwise the parent element's left or right [or root] would have to be set to NULL).
Your requirement is that you don't want to use recursion.
Any kind of traversal is not possible in O(n) time without use of a stack/queue (implicitly or explicitly). So we will use a stack (made using an array) and use it to delete all the nodes.
I understand that you have the size of the BST known, so you can create an array of appropriate size as -
struct Node* stack[bst->size];
int top = -1;
This stack will hold all the elements to be processed.
We will first add the root to the stack -
if(bst->root)
stack[++top] = bst->root;
Now we need to process all the nodes in the tree using a loop -
while(top>=0){
//Pop one node -
struct Node* node = stack[top--];
//Add its children to the stack;
if(node->left)
stack[++top] = node->left;
if(node->right)
stack[++top] = node->right;
// Now free the node as
free(node);
}
That is all, one by one each node will be added to the stack and the stack will become empty when all the nodes are done.
Also as a side note, in your insert function you need to do bst->size++ in the if(bst->root == NULL) branch. Else your size will be one less than actual number of nodes.
I am trying to figure out how to append a node to the link list.
I feel like I am almost there but after staring at the code for a while now I cant think of whats wrong with it.
I have to mention that after adding first int to the list I get segmentation fault...
typedef struct node
{
int data;
struct node* next;
}
node;
node* head;
void append(node* pHead, int data)
{
node* current = pHead;
node* newNode = NULL;
newNode = (node*)malloc(sizeof(node));
newNode->data = data;
newNode->next = NULL;
if (current == NULL)
pHead = newNode;
else
{
while (current->next != NULL)
current = current->next;
}
current->next = newNode;
}
int main(void)
{
head = NULL;
int howMany;
int num;
printf("how many?");
scanf("%d", &howMany);
for (int i = 0; i < howMany; i++)
{
printf("** %d ** number: ", i+1);
scanf("%d", &num);
append(head, num);
}
Where is my error?
I think the problem is here:
if (current == NULL)
pHead = newNode;
else
{
while (current->next != NULL)
current = current->next;
}
current->next = newNode;
That last line, current->next = newNode, should be inside the else body, otherwise you will try to dereference a NULL pointer when current is NULL.
So, it should be:
if (current == NULL)
pHead = newNode;
else
{
while (current->next != NULL)
current = current->next;
current->next = newNode;
}
Another problem is that you never modify head. You only modify the private, local copy of the head pointer inside append(). This modification is not visible outside of append(), so the program ends up leaking memory and you can never access the list (because head is always NULL). You can either make pHead a node ** (so that modifications to *pHead are visible), or instead you can modify head inside append(), instead of passing it as an argument. This will work because you won't be modifying a private local copy. Here's how append() should look like:
void append(int data)
{
node* current = head;
node* newNode = NULL;
newNode = (node*)malloc(sizeof(node));
newNode->data = data;
newNode->next = NULL;
if (current == NULL)
head = newNode;
else
{
while (current->next != NULL)
current = current->next;
current->next = newNode;
}
}
You do current->next = newNode; even if current is NULL.
You must return from function when (current == NULL):
if (current == NULL) {
pHead = newNode;
return;
}
else
{
while (current->next != NULL)
current = current->next;
}
current->next = newNode;
or put current->next = newNode; in else statement:
if (current == NULL) {
pHead = newNode;
}
else
{
while (current->next != NULL)
current = current->next;
current->next = newNode;
}
Full example:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node* next;
}
node;
node* head;
void append(node* pHead, int data)
{
node* current = pHead;
node* newNode = NULL;
newNode = (node*)malloc(sizeof(node));
newNode->data = data;
newNode->next = NULL;
if (current == NULL) {
pHead = newNode;
return;
}
else
{
while (current->next != NULL)
current = current->next;
}
current->next = newNode;
}
int main(void)
{
head = NULL;
int howMany;
int num;
printf("how many?");
scanf("%d", &howMany);
for (int i = 0; i < howMany; i++)
{
printf("** %d ** number: ", i + 1);
scanf("%d", &num);
append(head, num);
}
}
I am trying to read from a list that has 1 word per line and 20 lines, and then add each word to the end of a linked list. My problem is that when I print out the linked list at the end it is printing that last word in the file 20 times instead of each word once. I have been working on this for hours and can't figure out what i'm doing wrong.
In my main I have
while (!feof(input)) {
fscanf(input, "%s", currentName);
head = insert(head, currentName);
}
print(head);
delete(head);
Insert Function
node* insert(node* head, char* name) {
node *temp = NULL;
if (head == NULL) {
head = create_node(name);
}
else {
temp = head;
while(temp->next != NULL){
temp = temp->next;
}
temp->next = create_node(name);
}
return head;
}
Create Function
node* create_node(char* name) {
node *newNode;
newNode = malloc(sizeof(node));
if(newNode == NULL) {
printf("Failed to create node");
}
newNode->name = name;
newNode->next = NULL;
return newNode;
}
Print and Delete
void print(node* head){
while (head != NULL) {
printf("%s -> ", head->name);
head = head->next;
}
printf("NULL\n");
}
void delete(node* head) {
node *temp = NULL;
while(head != NULL) {
temp = head;
head = head->next;
free(temp);
}
}
You're saving the address of the same buffer back in main() for each and every insertion. Each node is simply holding the base address of currentName, the content of which is changed with each input processed. Therefore you have a linked list of structures containing name pointers, where each points to the same buffer (currentName). Thus the last one will be the only one you see.
You need to dynamically allocate space for the name in create_node. The following uses the POSIX function strdup() to do this, though you're perfectly free to use a strlen/malloc combination if you desire.
node* create_node(char* name)
{
node *newNode;
newNode = malloc(sizeof(node));
if(newNode == NULL)
printf("Failed to create node");
newNode->name = strdup(name);
newNode->next = NULL;
return newNode;
}
Don't forget when you're cleanup up your linked list to free() each node name to avoid a memory leak.
void delete(node* head)
{
node *temp = NULL;
while(head != NULL)
{
temp = head;
head = head->next;
free(temp->name);
free(temp);
}
}
Unrelated: Your while-loop condition for loading your content is wrong. Read this answer to see why
I'm trying to add to my linked list only if the item I'm inserting isn't already in the link list but when I try to traverse it and print out all of the items nothing is printing out. I can't seem to see what I'm doing wrong. Any help would be appreciated
// my add function
void add(char *val)
{
printf("%s", val);// val is getting printed so i know its being passed in.
if(head == NULL){
struct node *new_node = (struct node *)malloc(sizeof(struct node));
head = new_node;
head->item = val;
head->next = NULL;
} else{
struct node *current = head;
struct node *newNode = (struct node *) malloc(sizeof(struct node));
if (newNode == NULL) {
exit(-1);
}
newNode->item = val;
newNode->next = NULL;
while (current != NULL) {
current = current->next;
}
current = newNode;
}
}
//my traverse function
void goThroughList() {
struct node *current = head;
while(current != NULL){
printf("%s\n",current->item);
current= current->next;
}
}
add doesn't successfully add anything once head has been assigned. It only updates a local current pointer. You could fix that by changing the code that searches for the tail of the list to
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
If this doesn't help, can you update your question to show how add is being called? (To rule out the possibility that the same char array is being used for multiple calls, leaving all nodes with their item pointers pointed to the same buffer.
Also, there is no code I can see that checks for duplicates. You could implement this inside the branch of add where head already existed by iterating through the list using strcmp to compare each node's item with val.
your add function is incorrect
try this one :
void add(char *val)
{
printf("%s", val);// val is getting printed so i know its being passed in.
if(head == NULL){
struct node *new_node = (struct node *)malloc(sizeof(struct node));
new_node->item = val;
new_node->next = NULL;
head = new_node;
}
else{
struct node *current = head;
while (current->next != NULL) {
if(strcmp(current->item, val) == 0)
return;
current = current->next;
}
struct node *new_node = (struct node *)malloc(sizeof(struct node));
new_node->item = val;
new_node->next = NULL;
current->next = new_node;
}
}
what list does this function go trought ?
void goThroughList() {
struct node *current = head;
while(current != NULL){
printf("%s\n",current->item);
current= current->next;
}
}
try this instead :
void goThroughList(struct node* llist)
{
if(llist)
{
printf("%s" , llist->item);
goThroughList(llist->next);
}
}