Copy an array to linked List in each data field - c

First, sorry if my question has already been answered. I found some threads that are (in a way) similiar but I was not able to solve my problem.
Second, I am new to single-linked-list in C so I would be happy if you could answer my question as easy as possible.
I made a simple linke-list, that has characters in it:
#include <stdio.h>
#include <stdlib.h>
// declaration of node
struct _Node_
{
char data_string;
struct _Node_ *next;
};
int main() {
//a simple linked list with 3 Nodes, Create Nodes
struct _Node_* head = NULL;
struct _Node_* second = NULL;
struct _Node_* third = NULL;
//allocate 3 Nodes in the heap
head = (struct _Node_*)malloc(sizeof(struct _Node_));
second = (struct _Node_*)malloc(sizeof(struct _Node_));
third = (struct _Node_*)malloc(sizeof(struct _Node_));
// assign data for head
head->data_string = 'H'; //assign value according struct
head->next = second; //points to the next node
// assign data for second
second->data_string = 'E';
second->next = third;
third->data_string = 'Y';
third->next = NULL;
return 0;
}
The linked list does now look like this:
/* Linked list _Node_
head second third
| | |
| | |
+---+---+ +---+---+ +----+------+
| 1 | o-----> | 2| o-------> | 3 | NULL |
+---+---+ +---+---+ +----+------+
*/
Let's assume I have 3 arrays with the following:
char name1[] = "Joe";
char name2[] = "Eve";
char name3[] = "Brad";
And my goal is to copy this array into each data field, so the result looks like this:
/* Linked list _Node_
head second third
| | |
| | |
+-----+---+ +-------+---+ +-------+------+
| Joe | o-----> | Eve | o-----> | Brad | NULL |
+-----+---+ +-------+---+ +-------+------+
*/
How can I achieve this? I already tried adding/changing the following:
...
struct _Node_
{
char data_string[8];
struct _Node_ *next;
};
...
...
char name1[] = "Joe";
char name2[] = "Eve";
char name3[] = "Brad";
// assign data for head
head->data_string = name1; //assign value according struct
head->next = second; //points to the next node
// assign data for second
second->data_string = name2;
second->next = third;
third->data_string = name3;
third->next = NULL;
...
But all I get after compiling is:
stack_overflow.c:27:23: error: array type 'char [8]' is not assignable
head->data_string = name1; //assign value according struct
~~~~~~~~~~~~~~~~~ ^
stack_overflow.c:31:25: error: array type 'char [8]' is not assignable
second->data_string = name2;
~~~~~~~~~~~~~~~~~~~ ^
stack_overflow.c:34:24: error: array type 'char [8]' is not assignable
third->data_string = name3;
~~~~~~~~~~~~~~~~~~ ^
3 errors generated.
Maybe someone could help, I appreciate any help.
Again, sorry if this is a duplicate but I am not able to solve this with other threads..

You asked for a code example:
struct Node
{
char *data_string;
struct Node *next;
};
struct Node *newNode (char *s)
{
struct Node *node;
if (!s) return 0; // error: no string
if (!(node= malloc(sizeof(struct Node)))) return 0; // no more memory
node->data_string= malloc(strlen(s)+1);
if (!node->data_string) {
free(node);
return 0;
}
strcpy(node->data_string,s);
node->next= 0;
return(node);
}
void freeNode(struct Node *node)
{
if (!node) return;
if (node->data_string) free(node->data_string);
free(node);
}
Notes:
you alocate the memory for the string 1 more than the length because a string in C has a null terminating character.
do not use underscores before an identifier name - those are reserved for the compiler.
do not cast the result of malloc. It returns a void pointer, which is compatible with any pointer type.
this example includes all required error checking.

Related

Using fgets to read lines from a file into Binary Search Tree

Currently i'm trying to store each separate line in my file into a string, and then store it in a binary search tree, but a problem occurs. For some reason when I print my BST only the last line is outputted and not the first 3. Below is my code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
int count;
char* key;
struct node* left;
struct node* right;
};
struct node *newNode(char* item)
{
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->key = item;
temp->left = NULL;
temp->right = NULL;
temp->count = 1;
return temp;
};
void printInorder(struct node* root)
{
if(root != NULL)
{
printInorder(root->left);
printf("%s \n", root->key);
printInorder(root->right);
}
}
struct node* insert(struct node* node, char* key)
{
if(node == NULL)//When tree is empty
return newNode(key);
if(strcmp(key, node->key) < 0)
node->left = insert(node->left, key);
if(strcmp(key, node->key) > 0)
node->right = insert(node->right, key);
return node;
};
int main()
{
struct node *root = NULL;
int i = 0;
char str[100];
FILE* fp;
fp = fopen("textFile.txt", "r");
if ((fp = fopen("textFile.txt","r")) == NULL)
{
printf("Could not open textFile.txt\n");
exit(1);
}
while(fgets(str, 100, fp) != NULL)
{
++i;
root = insert(root, str);
printf("%3d: %s", i, str);
}
printf("bst printed\n");
printInorder(root);
return 0;
}
textFile.txt contains
bob is working.
david is a new hire.
alice is bob's boss.
charles doesn't like bob.
And when the bst is printed the only line that is outputted is the last one
Charles doesn't like bob.
Any help would really be appreciated.
Notice that when you create a node with newNode, you store a copy of the pointer passed into it, rather than a copy of the string being pointed at. This means that every time you insert a value into the tree, it stores a pointer to the str buffer in main. In other words, after you do your first insertion, things look like this:
+------------+
| BST Node | str
+------------+ +---+---+---+---+---+...+---+
| key | ---------> | b | o | b | | i | | 0 |
+------------+ +---+---+---+---+---+...+---+
When you then read the next line of the file, you're overwriting str with the contents of that line, so the picture looks like this:
+------------+
| BST Node | str
+------------+ +---+---+---+---+---+...+---+
| key | ---------> | d | a | v | i | d | | 0 |
+------------+ +---+---+---+---+---+...+---+
Notice that your BST now acts as though it contains "david is a new hire" even though you never inserted that value. As a result, when you try inserting "david is a new hire" into the BST, nothing happens.
The same thing happens for the next few reads, until eventually you read the final line of the file, when things look like this:
+------------+
| BST Node | str
+------------+ +---+---+---+---+---+...+---+
| key | ---------> | c | h | a | r | l | | 0 |
+------------+ +---+---+---+---+---+...+---+
This is why you're only seeing the line about Charlie at the end - the BST is directing you to the single shared copy of the buffer.
To fix this, make your BST store copies of the strings passed into it, or copy the strings before storing them in the tree. For example, you might have the newNode function call strdup to get its own copy of the string to store:
struct node *newNode(char* item)
{
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->key = strdup(item); // <--- here!
/* TODO: Error-handling! */
temp->left = NULL;
temp->right = NULL;
temp->count = 1;
return temp;
};
That should fix your issue. Just make sure to deallocate everything when you're done!

Storing an array of structs in a linked list

I have an array of struts called arrayOfElements , each element being a struct called Element
typedef struct {
void* data;
} Element;
data is a void pointer as I dont know in advanced what type of variable will be stored
I've malloc'd this array to have 4 elements ( this is done by user input but ive hard coded 4 for this question)
Element* arrayOfElements;
arrayOfElements= malloc(4 * sizeof(Element));
Now to this point I can store strings and ints in arrayOfElements
Store Int
arrayOfElements[0].data = malloc( sizeof(int) );
int *ptr = arrayOfElements[0].data;
*ptr = 65;
Store String
arrayOfElements[0].data = malloc( strlen(str) + 1 );
strcpy( arrayOfElements[0].data, str );
And that all works. My Issue is how do I got about making a linked List and making each element store an instance of arrayOfElements
so far my linked list is
typedef struct LinkedListNode {
void** ElementArray;
struct LinkedListNode* next;
} LinkedListNode;
typedef struct {
LinkedListNode* head;
} LinkedList;
so the void** ElementArray will point to each arrayOfElements
void insert(LinkedList* head, Element inArrayOfElements)
{
LinkedListNode insertNode;
/* Points ElementArray to inArrayOfElements */
HOW DO I DO THIS AS ElementArray is a void**
/* Points next to the head */
(*insertNode).next = head;
/* Re-points head to new head of Linked List */
head = insertNode;
}
My Goal is to have something like this
LINKEDLIST
+---+ +---+---+----+
| | -> | | | | arrayofElements
+---+ +---+---+----+ +---+---+----+
| | -------------------> | | | |
+---+ +---+---+----+ +---+---+----+
| | -> | | | |
+---+ +---+---+----+ +---+---+----+
| | -------------------> | | | |
+---+ +---+---+----+
Question / TL;DR
My question is how do I make void** ElementArray (in the linked list) point to arrayOfElements.
If I understand your question correct, there is no need for double pointers. Just do:
typedef struct LinkedListNode {
Element* data;
struct LinkedListNode* next;
} LinkedListNode;
LinkedListNode* insert(LinkedListNode* head, Element* inArrayOfElements)
{
LinkedListNode* insertNode = malloc(sizeof(LinkedListNode));
insertNode->next = head;
insertNode->data = inArrayOfElements;
return insertNode;
}
Use it like:
head = insert(head, someArrayOfElements);
Note: The real code should check for NULL pointers but I omitted that for simplicity.

Reverse direction of pointers in doubly linked list

I have a circular doubly linked list and I want to change the direction of all the next and prev pointers. I can't really figure out what the source of the error is. When I print the reversed list, it gets the first two numbers correct but past that point the links list stops printing.
struct Link
{
TYPE value;
struct Link * next;
struct Link * prev;
};
struct CircularList
{
int size;
struct Link* sentinel;
};
static void init(struct CircularList* list)
{
list->sentinel = (struct Link *) malloc(sizeof(struct Link));
list->sentinel->next = list->sentinel;
list->sentinel->prev = list->sentinel;
list->size = 0;
}
struct CircularList* circularListCreate()
{
struct CircularList* list = malloc(sizeof(struct CircularList));
init(list);
return list;
}
void circularListAddFront(struct CircularList* list, TYPE value)
{
struct Link *newLink = (struct Link *) malloc(sizeof(struct Link));
newLink->value = value;
newLink->next = list->sentinel->next;
newLink->prev = list->sentinel;
list->sentinel->next = newLink;
if(circularListIsEmpty(list)) {
list->sentinel->prev = newLink;
}
list->size++;
}
void circularListRemoveFront(struct CircularList* list)
{
struct Link *temp = list->sentinel->next;
temp->next->prev = list->sentinel;
list->sentinel->next = temp->next;
free(temp);
list->size--;
}
void circularListRemoveBack(struct CircularList* list)
{
struct Link *temp = list->sentinel->prev;
temp->prev->next = list->sentinel;
list->sentinel->prev = temp->prev;
free(temp);
list->size--;
}
void circularListReverse(struct CircularList* list)
{
struct Link *link = list->sentinel->next;
while(link != list->sentinel) {
struct Link *nextTemp = link->next;
struct Link *prevTemp = link->prev;
link->prev = link->next;
link->next = prevTemp;
link = nextTemp;
}
struct Link *temp = list->sentinel->next;
list->sentinel->next = list->sentinel->prev;
list->sentinel->prev = temp;
}
If I run the following to test this I get the output 5 4 1 2 2 1 and then terminates with no errors.
struct CircularList *deque = circularListCreate();
circularListAddBack(deque, 1);
circularListAddBack(deque, 2);
circularListAddBack(deque, 3);
circularListAddFront(deque, 4);
circularListAddFront(deque, 5);
circularListAddFront(deque, 6);
circularListRemoveFront(deque);
circularListRemoveBack(deque);
circularListPrint(deque);
circularListReverse(deque);
circularListPrint(deque);
There's a bug in your circularListAddFront function, and (though not shown) probably also in circularListAddBack:
Assume this state of the list:
p+SENTINEL+n
| A |
-----|------
Now, let's say you add 42 to the front. You first allocate a new node and set its value and pointers. Also you set the sentinel next pointer:
struct Link *newLink = (struct Link *) malloc(sizeof(struct Link));
newLink->value = value;
newLink->next = list->sentinel->next;
newLink->prev = list->sentinel;
list->sentinel->next = newLink;
This leads to the following state:
p+SENTINEL+n
| A |
-----| |
| |
------ |
| | |
p+42+n |
A |
| |
---------
Which is not fine, because the prev pointer of the sentinel still points to itself. You fix that directly after that:
if(circularListIsEmpty(list)) {
list->sentinel->prev = newLink;
}
list->size++;
This gives the desired result:
p+SENTINEL+n
--| A |
| | |
| ------ |
| | | |
| p+42+n |
| A |
| | |
--------------
This is fine. Now let's add a 21 to the glorious list:
----------
| |
| V
| p+SENTINEL+n
| --| A |
| | | |
| | ------ |
| | | | |
| | p+42+n |
| | A |
| | | |
| -----| |
| | |
| p+21+n |
--| A |
| |
-----------
That's the state right before that if, and it has the same issue as before: There's one prev pointer wrong, this time it's not sentinels but the one of node 42: It should point to its previous node, which is now 21, and not to the sentinel.
Since the if is not taken, the sate remains. You don't notice it until reversing the list because you don't use the prev pointers until then.
To fix that, get rid of the if and correct the logic unconditionally:
When you insert a new node to the front ("after the sentinel"), then you need to change the prev pointer of the node that was at the front before and point it to the new node:
newLink->next = list->sentinel->next;
newLink->prev = list->sentinel;
list->sentinel->next->prev = newLink; // ADDITION
list->sentinel->next = newLink;
The code for reversing the list seems fine, though. And for now, I'm done with "line art ASCII graphics" :D

How to access values from pointers to pointers in C?

I am writing a program that is attempting to implement a hash table in C. It has to use a pointer to a pointer as an attribute in a struct data type. Here is the code of the relevant structs.
struct node {
char * data;
struct node * next;
};
struct hashtable {
int size;
struct node ** table;
};
Part one of question:
I have been doing a lot of research to figure out just how pointers to pointers work but I still can't seem to get my head around it. Every example I've found assigns two different pointer names to the first and second pointer. eg
x = 5;
*p = &x;
**q = &p;
What about the case above "struct node ** table;"
Is ** table the same as **q in this case?
What would the values of q , *q and **q be in this case? is q = 5 and then *q and **q work back through the addresses or is **q = 5 and *q and q store the addresses?
Part two of question:
How do I access a pointer to a pointer within another function? Here is the code I have right now.
struct hashtable * hashtable_new(int size){
struct hashtable *newTable;
if ( size < 1 )
{
return NULL;
printf("Its returning Null.");
}
else
{
newTable = malloc(sizeof(struct hashtable));
newTable -> size = size;
newTable -> table = malloc(sizeof(struct node) * size);
int i;
for (i = 0; i < size; i++ )
{
newTable -> table[i] = NULL;
}
fprintf(stderr, "Table has been created.");
return newTable;
}
};
I'm not sure I understand how to access either the pointer or the pointer to a pointer through the -> symbol. Is it "newtable -> table" or "newtable -> -> table" ?
The aim of the table is essentially to be a 2d table, where the list is primarily 1D and can spread to 2D to deal with collisions in the hashing.
End note:
Hopefully I've provided enough information to make contextual sense asking this question. Its my first time asking a question on stackoverflow so feel free to ask me extra question, provide CC or flag any mistakes I've made asking this question.
Thank you!
There are several ways to look at a pointer to a pointer. One way is as you described with
int x = 5;
int *p = &x;
int **q = &p;
After all that, the following are all true:
**q == *p == x == 5
*q == p == &x
q == &p
However, another way to look at a pointer to a pointer is as an array of pointers. For example, assume the declaration:
int *arr[10];
Except when it is the operand of the sizeof or unary & operands, the expression arr will be converted ("decay") from type "10-element array of int *" to "pointer to int *", or int **.
If you want to dynamically allocate an N-element array of pointers to struct node, you would write
struct node **arr = malloc( sizeof *arr * N );
You would use the [] subscript operator to access elements in arr as you would a normal array. Since arr has type struct node **, each arr[i] has type struct node *, so you would access members of the structure like so:
arr[i]->data = "foo"; // use -> when the LHS is a pointer to a struct or union
arr[i]->next = NULL;
struct hashtable allows you to create multiple hashtable instances, each one of which has a size member and an array of struct node * which you allocate at runtime, like so:
struct hashtable h1;
h1.size = 512;
h1.table = calloc( h1.size, sizeof h1.table ); // calloc initializes all elements of
// h1.table to NULL
if ( !h1.table )
{
// calloc call failed, handle as appropriate
}
You'd insert a new element into the table like so:
/**
* Assumes we know that the string data points to is not already in
* the table. hashfunc is a pointer to the hashing function.
*/
void insert( struct hashtable *h, const char *data, size_t (*hashfunc)(const char *))
{
/**
* Create a new table entry. Remember that table is an array of
* *pointers* to struct node, and that each array element is initially
* NULL. We still need to allocate something for that table entry
* to point *to*.
*/
struct node *newNode = malloc( sizeof *newNode );
if ( !newNode )
{
/**
* Memory allocation for new node failed, handle as appropriate
*/
}
newNode->data = malloc( strlen( data ) + 1 );
strcpy( newNode->data, data );
/**
* Get the table index by computing the hash and modding against the
* table size.
*/
size_t idx = hashfunc( data ) % h->size;
/**
* Insert newNode at the head of the list starting at
* h->table[idx]. In reality you'd probably want to insert
* strings in order, but for a toy example this is good enough.
*/
newNode->next = h->table[idx]; // newNode->next points to the previous head of list
h->table[idx] = newNode; // newNode becomes new head of list.
}
When you're done, your hashtable looks something like this:
+---+
h1: | | size
+---+ +---+ +---+---+ +---+---+
| | table ----> | | --> | | | --> | | |
+---+ +---+ +---+---+ +---+---+
| |
+---+ +---+---+
| | --> | | |
+---+ +---+---+ +---+---+ +---+---+
| | --> | | | --> | | | --> | | |
+---+ +---+---+ +---+---+ +---+---+
...
table points to an array of struct node *, each of which may point to an instance of struct node, each of which may point to another instance of struct node. In the picture above, two strings have hashed to table[0],
one to table[2], and three to table[3].
Here's a little program that might help you, it might be worth playing about with pointers for a bit and inspecting them, output addresses etc.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
char *p1 = "String of text.";
char **p2;
/**
* We can print the avtual address of *p1 and **p2...
*/
fprintf(stdout, "p1 = %p\n", p1);
fprintf(stdout, "p2 = %p\n", p2);
/**
* Now if we point p2 at p1 we can then check what address
* *p2 points at...
*/
p2 = &p1;
fprintf(stdout, "*p2 = %p\n", *p2);
/**
* So if you think about it, *p2 should be the same at p1
* if we print it as a string:
*/
fprintf(stdout, "p1 is %s\n*p2 is %s\n", p1, *p2);
exit(EXIT_FAILURE);
}
Hope this helps.
As for referencing the struct from another function, if you're passing a pointer to that structure you use a single -> to refer to any member of the struct...but you are allocating another struct within your struct - using a pointer.
Say I have
struct one {
char *string;
}
struct two {
struct *one a;
struct one b;
char *whatever;
}
If have a pointer to a struct two:
struct two *t;
And it had its member a allocated a struct one...then I'd reference the members of a using ->
t -> a -> string;
But b isn't a pointer so you would do:
t -> b.string;

Swap nodes in a singly-linked list

I am trying to swap two nodes. For example if the nodes are a and b I am passing the pointers
(a-1)->next and (b-1)->next which are basically nodes a and b.
void swap(struct stack **a,struct stack **b)
{
struct stack *temp1 = *a, *temp2 = *b, *temp3 = *b;
*a = *b;
(*b)->next = (temp1)->next;
temp2 = temp1;
(temp2)->next = temp3->next;
}
What am I doing wrong? When I am trying to print the nodes after calling the function it's an infinite loop. Please help.
Why Infinite loop?
Infinite loop is because of self loop in your list after calling swap() function. In swap() code following statement is buggy.
(*b)->next = (temp1)->next;
Why?: Because after the assignment statement in swap() function temp1's next starts pointing to b node. And node[b]'s next point to itself in a loop. And the self loop is reason for infinite loop, somewhere in your code where you traverse linked list.
Below I drawn to show how swap() works step-by-step. May be this help you to understand your error:
You didn't mention but I am assuming linked list having following relation between a and b: (read red comments)
(step-1):
+----+----+----+ +---+----+----+
| one |----->| two |
+----+----+----+ +---+---+-----+
^ ^ ^ ^
| | | |
| *a | *b
| |
temp1 temp2, temp3 "after assignment to temp variables"
(step-2): ^
|
*a = *b | *a "<--- next step"
(step-3): The buggy statement
(*b)->next = (temp1)->next; "Change link: (temp1)->next; is `two` node"
" *b is `two`, So Self loop"
+----+----+----+ +---+----+----+ <---|
| one | | two |-----|
+----+----+----+ +---+---+-----+
^ ^ ^ ^
| | | |
| | *b *a
| |
temp1 temp2, temp3 " after assignment to temp"
See (temp1)->next; is actually b and you are assigning (*b)->next = (*b) by doing (*b)->next = (temp1)->next; hence adding a self loop.
(step-4):
I think with the diagram you can easily understand what last two lines of your swap() code are doing:
temp2 = temp1;
(temp2)->next = temp3->next;
Following is my diagram for this two lines:
temp2 = temp1;
+----+----+----+ +---+----+----+ <---|
| one | | two |-----| "<--- Self loop"
+----+----+----+ +---+---+-----+
^ ^ ^ ^
| | | |
| | *b *a
| |
temp2 = temp1; temp3
(step-5): Even last line of your function swap() left loop as below:
(temp2)->next = temp3->next; " last line of your code"
+----+----+----+ +---+----+----+ <---|
| one |----->| two |-----| "<-- Self loop"
+----+----+----+ +---+---+-----+
^ ^ ^ ^
| | | |
| | *b *a
| |
temp2 = temp1; temp3
So loop still there at two node so infinite loop.
How to swap two nodes in single linked list?
One way is swap node's data instead of swapping node's position it self in linked list (as I commented to your question). But you wants to swap node's position in list.
Well this good! if node data size is larger, that time its better to swap node's position rather then swap node's data(swapping data will be bad choice)
Because you having single linked list, to swap any two arbitrary nodes in list you need there previous node addresses too. (this is the point you don't consider in your swapping logic)
WHY need previous pointers?:
Suppose after some successful insert(push) operations, your list becomes as follows:
0 <--------TOP - "head"
9 <--p
2
6 <--q
5
A horizontal diagram- Suppose you want to swap say two nodes (q) and (p):
+---+ +---+ +---+ +---+ +---+
| 0 |--->| 9 |--->| 2 |--->| 6 |--->| 5 |---
+---+ +---+ +---+ +---+ +---+ |
^ ^ ^ null
| | |
| (q) (p)
(head)
As I said, to swap we need previous pointers. You need to think about following
(In theory, I am writing for specific nodes (p) and (q) just to keep explanation simple. but my implementation is quit general):
In list previous pointers:
node[0] points to node[9] that is (q), and
node[2] points to node[6] that is (p)
And
node[9] points to node[2]
node[6] points to node[5]
NOTICE: If you want to swap two nodes say node[ 9 ] and node[ 6 ] then you should use pointers of the nodes previous to these two nodes.
For example: two swap node[ 9 ] and [ 6 ], you also need to change next pointer of node[ 0 ] and next pointer of node[ 2 ] in above diagram.
How would be the list after swapping this two nodes?
+---+ +---+ +---+ +---+ +---+
| 0 |--->| 6 |--->| 2 |--->| 9 |--->| 5 |---
+---+ +---+ +---+ +---+ +---+ |
^ ^ ^ null
| | |
| (p) (q)
(head)
What is now in previous nodes [o] and [2]?
After swapping, In list previous pointers
node[0] points to node[6] that is (q), and
node[2] points to node[9] that is (p)
And
node[9] points to node[5]
node[6] points to node[2]
So if you want to swap two nodes; there immediate previous node also effects and because list is single link list you need previous pointers too.
How to find previous node pointers?
Suppose you want to swap any two nodes node[p] and node[q] then you can use head pointer to find previous node.
So swap function syntax (In my implementation) is like:
void swap(struct stack **head, // head node
struct stack **a, // first candidate node to swap
struct stack **b); // first candidate node to swap
And you will call function like:
swap(&head, &p, &q);
Definition: (To understand code please read comments I added at almost each line)
void swap(struct stack **head,
struct stack **a,
struct stack **b){
// first check if a agrgument is null
if( (*head) == NULL || // Empty list
(*a) == NULL || (*b) == NULL){ // one node is null
// Nothing to swap, just return
printf("\n Nothing to swap, just return \n");
return;
}
// find previos nodes
struct stack* pre_a = get_prevnd(*head, *a);
struct stack* pre_b = get_prevnd(*head, *b);
//Now swap previous node's next
if(pre_a) pre_a->next = (*b); // a's previous become b's previous, and
if(pre_b) pre_b->next = (*a); // b's previous become a's previous
//Now swap next fiels of candidate nodes
struct stack* temp = NULL;
temp = (*a)->next;
(*a)->next = (*b)->next;
(*b)->next = temp;
//change head: if any node was a head
if((*head)==(*a))
*head = *b;
else
if((*head)==(*b))
*head = *a;
}
In swap() function you can notice that I call a helper function get_prevnd(, );. This function returns address of previous node in list. In The function get_prevnd(, );, first argument is list head and second argument is node for which you are looking for.
// find previous node function()
struct stack* get_prevnd(
struct stack* head,
struct stack* a
){
if(head == a){
// node[a] is first node
return NULL;
}
struct stack* temp = head; // temp is current node
struct stack* pre_a = NULL;
while(temp && temp!=a){ //search while not reach to end or the node
pre_a = temp; // find previous node
temp = temp->next;
}
if(temp!=a){// node[a] not present in list
fprintf(stderr, "\n error: node not found!\n");
exit(EXIT_FAILURE); // bad technique to exit()
}
return pre_a;
}
And fortunately the code is WORKING :). Below is link for online test of this code. I have tested for various kind of inputs.
CodePad: To Swap node in single linked list. Please check output.
And sorry for bad English
I was hoping for cut-and-paste code, but didn't find it. If anyone is still interested, this is the answer. I did the brute force analysis of all 3 cases.
// swaps nodes at locations *sp and *tp
struct stack *s = *sp; // store locations to prevent overwritten bugs
struct stack *t = *tp;
if(&t->next == sp) { // order u (tp)-> t (sp)-> s -> ...
t->next = s->next;
s->next = t;
*tp = s;
} else if(&s->next == tp) { // order u (sp)-> s (tp)-> t -> ...
s->next = t->next;
t->next = s;
*sp = t;
} else { // disconnected u (sp)->s -> ..., v (tp)->t -> ...
struct stack *next = s->next;
s->next = t->next;
t->next = next;
*sp = t;
*tp = s;
}
// If you track the end of your list, it be the one pointing to NULL.
if(s->next == NULL) {
end = &s->next;
} else if(t->next == NULL) {
end = &t->next;
}
Note: This code works if sp == tp, but assumes you don't have the pathological case where BOTH &s->next == tp && &t->next == sp (starting with cycle).
"KING KHAN"
SwapanyTwoNodeData(int, int); this function take two integer as parameter and swap these
node data.
1->2->6->3->4->5
SwapanyTwoNodeData (2,4);
1->3->6->2->4->5
100% Working Function. . . . Enjoy.
void Swap_Any_Two_Locations_data(int x,int x1){
if(head!=NULL){
int count=1,count1=1;
Node *temp,*temp1;
temp=head;
temp1=head;
while(temp->next!=NULL && count!=x ){
temp=temp->next;
count++;
}
while(temp1->next!=NULL && count1!=x1){
temp1=temp1->next;
count1++;
}
if(count==x && count1==x1){
int z=0;
z=temp->info;
temp->info=temp1->info;
temp1->info=z;
cout<<"Data Swapped"<<endl;
}
}
}

Resources