#include<stdio.h>
struct llist {
int data;
struct llist *next;
};
typedef struct llist list;
struct graph {
int V;
list **adj;
};
typedef struct graph graph;
graph* create_graph(int V) {
list **adj = (list**)malloc(sizeof(list*)*V);
graph *a = (graph*)malloc(sizeof(graph));
a->V = V;
a->adj = adj;
return a;
}
void insert_list(list **head, int v) {
list *new_node, *temp_node, *last_node;
new_node = (list*)malloc(sizeof(list));
new_node->data = v;
new_node->next = NULL;
printf("\n hi %d", head);
/*
* head is empty, point the head to temp and return.
*/
if (*head == NULL) {
*head = new_node;
return;
}
temp_node = *head;
do{
last_node = temp_node;
temp_node = temp_node->next;
}while(temp_node);
last_node->next = new_node;
}
void addedge(graph *g, int u, int v) {
insert_list(&(g->adj[u]), v);
}
int
main() {
int V = 10;
graph *a = create_graph(V);
printf("\n graph created");
addedge(a, 1,2);
addedge(a,1,5);
addedge(a,2,1);
addedge(a,2,5);
addedge(a,2,3);
addedge(a,2,4);
addedge(a,3,2);
addedge(a,3,4);
addedge(a,4,2);
addedge(a,4,5);
addedge(a,4,3);
addedge(a,5,4);
addedge(a,5,1);
addedge(a,5,2);
return 0;
}
In this code, by printing messages, I have found is create_graph function executes properly and returns a graph. Then addedge is being called, In it, if(*head==NULL) part always returns false (Don't know why, first time it should return true). Then it goes ahead in do while loop and that keep executing till infinity and code terminates.
What I am trying to do is I have a structure called graph, with a integer variable V and array of linked list variable adj (represents adjacency list). And then create graph will initialise a graph variable and return it.
Addedge(V,u,v) will add edge v to u (means v is adjacent to u). so adj[0....V-1] is a array of linked list. so if edge 1 is adjacent to 2 and 3, then list will look like 1->2->3.
Comment If more info needed. I don't know what why *head is not null the first time and why the while loop never terminates.
Thanks a lot in advance.
By trail and error, I found the mistake.
In function create graph, after initialising the list, each individual list also must be initialised to NUll, otherwise it will have junk stuff.
Below is correct code :
graph* create_graph(int V) {
list **adj = (list**)malloc(sizeof(list*)*V);
int i;
for (i = 0; i < V; ++i) {
adj[i] = NULL;
}
graph *a = (graph*)malloc(sizeof(graph));
a->V = V;
a->adj = adj;
return a;
}
Related
so I have this function which does a depth first search traversal of a graph and prints out the nodes traversed. But instead of printing the nodes I want this function to return the node it newly moved to, return one node per call of the function.
when I call the function with the start node 0, it should return the next node in traversal (order of the nodes when traversing is printed out when running the program, along with the graph's adjacency list), which is 1 but it is returning 3.
the traversal order is: 1 2 3 2 4 5 4 6
below is what I have tried:
int DFS(struct Graph* graph, int vertex) {
struct node* adjList = graph->adjLists[vertex];
struct node* temp = adjList;
int back = 0;
graph->visited[vertex] = 1;
while (temp != NULL) {
int connectedVertex = temp->vertex;
if (graph->visited[connectedVertex] == 0) {
if ( back==1 ) {
return vertex;
printf("node: %d\n", vertex);
}
printf("node 1: %d\n", connectedVertex);
return DFS(graph, connectedVertex);
back = 1;
}
temp = temp->next;
}
return vertex;
}
and here is the function without the return statements (originally a void function):
void DFS(struct Graph* graph, int vertex) {
struct node* adjList = graph->adjLists[vertex];
struct node* temp = adjList;
int back = 0; // = "We have already expanded vertex"
graph->visited[vertex] = 1;
while (temp != NULL) {
int connectedVertex = temp->vertex;
if (graph->visited[connectedVertex] == 0) {
if ( back==1 ) // Report the revisited node
printf("node: %d\n", vertex);
printf("node: %d\n", connectedVertex);
DFS(graph, connectedVertex);
back = 1; // Tag this node as having been expanded.
}
temp = temp->next;
}
}
and here is my full program:
// DFS algorithm in C
#include <stdio.h>
#include <stdlib.h>
struct node {
int vertex;
struct node* next;
};
struct node* createNode(int v);
struct Graph {
int numVertices;
int* visited;
struct node** adjLists;
};
void DFS(struct Graph* graph, int vertex) {
struct node* adjList = graph->adjLists[vertex];
struct node* temp = adjList;
int back = 0; // = "We have already expanded vertex"
graph->visited[vertex] = 1;
while (temp != NULL) {
int connectedVertex = temp->vertex;
if (graph->visited[connectedVertex] == 0) {
if ( back==1 ) // Report the revisited node
printf("node: %d\n", vertex);
printf("node: %d\n", connectedVertex);
DFS(graph, connectedVertex);
back = 1; // Tag this node as having been expanded.
}
temp = temp->next;
}
}
// Create a node
struct node* createNode(int v) {
struct node* newNode = malloc(sizeof(struct node));
newNode->vertex = v;
newNode->next = NULL;
return newNode;
}
// Create graph
struct Graph* createGraph(int vertices) {
struct Graph* graph = malloc(sizeof(struct Graph));
graph->numVertices = vertices;
graph->adjLists = malloc(vertices * sizeof(struct node*));
graph->visited = malloc(vertices * sizeof(int));
int i;
for (i = 0; i < vertices; i++) {
graph->adjLists[i] = NULL;
graph->visited[i] = 0;
}
return graph;
}
void sortedInsert(struct node** head_ref,
struct node* new_node)
{
struct node* current;
/* Special case for the head end */
if (*head_ref == NULL
|| (*head_ref)->vertex
>= new_node->vertex) {
new_node->next = *head_ref;
*head_ref = new_node;
}
else {
/* Locate the node before
the point of insertion */
current = *head_ref;
while (current->next != NULL
&& current->next->vertex < new_node->vertex) {
current = current->next;
}
new_node->next = current->next;
current->next = new_node;
}
}
// Add edge
void addEdge(struct Graph* graph, int src, int dest) {
// Add edge from src to dest
sortedInsert(&graph->adjLists[src], createNode(dest));
// Add edge from dest to src
sortedInsert(&graph->adjLists[dest], createNode(src));
}
// Print the graph
void printGraph(struct Graph* graph) {
int v;
for (v = 0; v < graph->numVertices; v++) {
struct node* temp = graph->adjLists[v];
printf("\n Adjacency list of vertex %d\n ", v);
while (temp) {
printf("%d -> ", temp->vertex);
temp = temp->next;
}
printf("\n");
}
}
int main() {
struct Graph* graph = createGraph(7);
addEdge(graph, 0, 1);
addEdge(graph, 0, 3);
addEdge(graph, 1, 2);
addEdge(graph, 2, 3);
addEdge(graph, 2, 4);
addEdge(graph, 4, 5);
addEdge(graph, 4, 6);
printGraph(graph);
DFS(graph, 0);
return 0;
}
Help would be much appreciated.
" I want this function to return the node it newly moved to, return one node per call of the function."
This is a bad idea, because your function is recursive.
To get the nodes traversed in order add the visited node index to a global data structure.
Note: Recursion is the correct way to go here. Returning the node visited from the recursive function will not work.
Allow me to describe how I would do this:
When searching through graphs, the concept of a "visitor" is useful. A visitor is a function that the search code calls each time it reaches a new node. It makes writing the search code slightly more complex, but you need only do it once. Once written you can adapt the algorithm to do different purposes without disturbing your carefully tested and optimized search code. In this case, all the visitor need do is record the node indexes as they are visited.
Note that once you have the visitor written, you can easily change the searching algorithm ( say from depth first to breadth first ) without writing new code.
Your visitor can look like this in C++
/// in global namespace
std::vector<int> gvIndexNodeVisitedOrder();
void visitor( int indexNode )
{
gvIndexNodeVositedOrder.push_back( indexNode );
}
The searching code looks like:
void depthFirstRecurse(
int v )
{
// Call the visitor
visitor(v);
// remember this node has been visited
gvNodeVisited[v] = 1;
// look at adjacent nodes
for (int w : adjacent(v)) {
// check node has not been visited
if (!gvNodeVisited[w])
{
// continue search from new node
depthFirstRecurse(w);
}
}
}
Note: I have placed stuff in the global namespace because the original question is tagged C. In reality I would use a C++ class and make the "globals" private attributes and methods of the class.
I added this two fuctions:
// Adds a node to a list of nodes
void addNode(struct node** nodeList, int vertex){
struct node *temp = *nodeList;
if(*nodeList == NULL){
*nodeList = createNode(vertex);
}else{
while(temp->next != NULL){
temp = temp->next;
}
temp->next = createNode(vertex);
}
}
// Prints a list of nodes
void printNodeList(struct node* nodeList) {
struct node* temp = nodeList;
while(temp != NULL){
printf("%d", temp->vertex);
if(temp->next != NULL){
printf(" -> ");
}
temp = temp->next;
}
printf("\n");
}
and modified DFS and main as follow:
// added last argument
void DFS(struct Graph* graph, int vertex, struct node** nodeList) {
struct node* adjList = graph->adjLists[vertex];
struct node* temp = adjList;
graph->visited[vertex] = 1;
addNode(nodeList, vertex); // added this
while (temp != NULL) {
int connectedVertex = temp->vertex;
if (graph->visited[connectedVertex] == 0) {
printf("node: %d\n", connectedVertex);
DFS(graph, connectedVertex, nodeList);
addNode(nodeList, vertex); // added this
}
temp = temp->next;
}
}
int main() {
struct node* nodeList = NULL;
struct Graph* graph = createGraph(7);
addEdge(graph, 0, 1);
addEdge(graph, 0, 3);
addEdge(graph, 1, 2);
addEdge(graph, 2, 3);
addEdge(graph, 2, 4);
addEdge(graph, 4, 5);
addEdge(graph, 4, 6);
printGraph(graph);
DFS(graph, 0, &nodeList);
printNodeList(nodeList);
return 0;
}
If I would have to define the traversal order of the nodes, in your example graph it would not be 1 -> 2 -> 3 -> 2 -> 4 -> 5 -> 4 -> 6 but rather 0 -> 1 -> 2 -> 3 -> 2 -> 4 -> 5 -> 4 -> 6 -> 4 -> 2 -> 1 -> 0, since I think that any time you "land" on a different node (either because you call DFS or because DFS gives back control to the caller), that "counts" in the path you're following to search the graph, and this until you're back to the main function, hence you've finished searching. Therefore in the DFS function above I implemented that, but if you need the order you mentioned, just add addNode(nodeList, vertex); below your printf statements and you should get it.
Since the function is recursive you can't really use the return statement to return the visited nodes, because what you want to have at the end is a list of elements and not just a single value. For instance in your code you defined the return type of DFS as int, this means that the function can only give you back a number, but when you call DFS in your main function you expect it to give you back a list of node that got visited. You may be able to figure out something returning a pointer to a data structure or maybe returning an int (the visited vertex) and calling something like addNode(list, DFS(g, vertex)) but you would still need to pass the list to DFS (otherwise you won't be able to call addNode(list,...) inside of it), so you would get addNode(list, DFS(g, vertex, list)), therefore I don't think you would get any advantage out of it, but I don't know.
What I did is to define a list in the main function and to pass it to the recursive function (does not need to return anything), which is then able to add the visited node to it when necessary. The first call to addNode(nodeList, vertex) happens only once per vertex since you never call DFS more than one time for any vertex, while the second happens every time you come back to a vertex after having searched into one of it's neighbors.
struct clist {
int pos;
char* color;
struct clist *next;
};
typedef struct clist sl_clist;
sl_clist *head = NULL;
sl_clist* link[5];
So i am trying to create multiple single linked circular lists and put them into a stack, every list will have the same types of data. In this case i am using the stack as an array. But i just cannot figure out how to create multiple linked lists from single type. I am a student so i am not very experienced on C. Thaks for the help in advance.
void create_list (int N, sl_clist* head){
int i;
sl_clist *new;
sl_clist *old;
if(N == 0){
head = NULL;
}
srand(time(0));
for(i = 0; i < N; i++){
new = (sl_clist*)malloc(sizeof(sl_clist));
if(i == 0){
head = new;
new -> color = color[(rand()%10)];
new -> pos = pos[i];
new -> next = head;
}
else{
new -> color = color[(rand()%10)];
new -> pos = pos[i];
old -> next = new;
new -> next = head;
}
old = new;
}
}
I have also tried creating multiple "head" variables but for some reason when i use them in this function(just imagine there are arrays for color and pos) they always return NULL.
Do not use global variables. Remove them.
sl_clist *head = NULL;
sl_clist* link[5];
Using local varaibles will "force" you to use a modular design that supports multiple lists.
Variables are passed by value:
head = new;
modifies a copy sl_clist* head of the original pointer passed as the argument. The original pointer is unaffected.
There are multiple ways you can solve that problem. You can return the new value:
sl_clist *create_list (int N, sl_clist* head){
...
return new; // or old value
}
int main() {
sl_clist *head = NULL;
head = create_list(5, head);
}
You can take the pointer by reference:
int create_list (int N, sl_clist **head){
...
*head = new; // set new value
(*head)->something = something; // be aware of operator precedence
}
int main() {
sl_clist *head = NULL;
create_list(5, &head); // head is getting modified
}
But I recommend doing a separate type for the head. That way the function is clear - it takes the head, specifically, not any list element. Be verbose:
struct sl_head {
struct clist *head;
};
int create_list(int N, struct sl_head *head) {
// ^^^^^^^^^^^^ - verbose, this is the head, not some element, less mistakces
head->head = new; // a bit more to type
head->head->something = something;
}
int main() {
struct sl_head head = {0}; // no longer a pointer
create_list(5, &head); // head is getting modified
}
Move srand(time(0)); to main(). It's not a function that you call when creating a list.
I want to create a linked list.
The user adds numbers and the idea is that the numbers are inserted to the list in descending order.
Here goes what I did, but when rearranging, it just orders the first number...
int addInputNumber(numberList **node){
numberList *temp;
int userInput;
temp = (numberList*)malloc(sizeof(numberList));
//Memory Check
if ( temp == 0 )//out of memory, return 0
return 0;
//Get the users input
printf("Give me a Number!\n");
scanf("%d",&userInput);
//Add it to the list.
temp->numbero = userInput;
///Link to the list.
temp->next = *node;
*node = temp;
//Lets cycle through the list.
numberList *temp2;
int helpNumber;
temp2 = *node;
//Rearrange the list.
while(temp2 != 0){
if(temp->numbero < temp2->numbero){
//Switch position..
helpNumber= temp2->numbero;
temp2->numbero = temp->numbero;
temp->numbero = helpNumber;
temp2 = *node;// If we change number, we must cycle from the beginning AGAIN.
}//eof if
temp2 = temp2->next;
}//eof while
return 0;
}//eof addNUmber function.
Here's the structure just in case:
typedef struct dynamicNumberList {
int numbero;
struct dynamicNumberList *next;
}numberList;
I've got 2 quick questions.
Why would it only arrange the first number?
This list adds a space towards the left (visually), how could I make it so I can add a space to the right?
You need to get into the habit of creating one function per task, instead of cramming everything into a single one. It makes the code easier to read and reuse and reduces the chance of errors.
A correct implementation could look like this:
#include <stdio.h>
#include <stdlib.h>
typedef struct s_List
{
int n;
struct s_List *next;
} List;
void print_list (List *head)
{
List *ptr;
for (ptr = head; ptr; ptr = ptr->next) {
printf ("%d\t", ptr->n);
}
putchar ('\n');
}
List * make_node (int n, List *next)
{
List * node = malloc (sizeof(List));
node->n = n;
node->next = next;
return node;
}
void insert_number_front (List **head, int n)
{
*head = make_node (n, *head);
}
void insert_number_after (List *prev, int n)
{
prev->next = make_node (n, prev->next);
}
// If HEAD is sorted, it will stay sorted after insertion
void insert_number_sorted (List **head, int n)
{
List *ptr;
List *ptr2;
// search for the rightmost node whose number is smaller than n.
ptr2 = NULL;
for (ptr = *head; ptr; ptr = ptr->next) {
if (ptr->n >= n)
break;
ptr2 = ptr;
}
// If such a node exists we insert the new node after it,
// otherwise we insert it at the front of the list.
if (ptr2) {
insert_number_after (ptr2, n);
}
else {
insert_number_front (head, n);
}
}
int input_number ()
{
int n;
printf ("enter a number: ");
scanf ("%d", &n);
return n;
}
int main ()
{
List *head = NULL;
int i;
// By adding elements exclusively with insert_number_sorted()
// we ensure the list is always sorted
for (i = 0; i < 5; i++) {
int n;
n = input_number ();
insert_number_sorted (&head, n);
}
print_list (head);
return 0;
}
To answer your second question, what you have here is a singly linked list, which can be described by a pointer to the first node. If you want to be able to insert nodes at the back you need to maintain an additional pointer to the last node. However this is not necessary in this case.
Write a function that rearranges a linked list to put the nodes in even positions after the nodes in odd positions in the list, preserving the relative order of both the evens and the odds.
I found this problem in the book Algorithm in c writtern by Sedgewick. I have tried but failed. I trid to put all nodes in even positions on another linked list. It's grateful for you to help me. A good idea is enough. Thanks :).
This is my Code in C.
/*
* File: rearranges.c <Exercise 3.36>
* Note: Write a function that rearranges a linked list to put the nodes in even
* positions after the nodes in odd positions in the list, preserving the
* relative order of both the evens and the odds.
* NOTICE: I think it's necessary to use linked list with a dummy head.
* Time: 2013-10-26 10:58
*/
#include <stdio.h>
#include <stdlib.h>
#define LEN 11
typedef struct node *link;
struct node {
int item;
link next;
};
/* Traverse a linked list with a dummy head. */
void traverse(link t) {
link x = t->next;
while (x != NULL) {
printf("%d ", x->item);
x = x->next;
}
putchar('\n');
}
/* Detach even positon nodes from a linked list. */
link detach(link t) {
link u = malloc(sizeof(*u));
link x = t, y = u;
/* x is odd position node. We should ensure that there's still one even
* position node after x. */
while (x != NULL && x->next != NULL) {
y->next = x->next;
x->next = x->next->next;
x = x->next;
y = y->next;
y->next = NULL;
}
return u;
}
/* Combine two linked list */
link combine(link u, link t) {
link x = u;
link y = t->next;
while (y != NULL) {
link n = y->next;
y->next = x->next;
x->next = y;
x = x->next->next;
y = n;
}
return u;
}
/* The function exchanges the position of the nodes in the list. */
link rearranges(link t) {
link u = detach(t);
link v = combine(u, t);
return v;
}
int main(int argc, char *argv[]) {
int i;
link t = malloc(sizeof(*t));
link x = t;
for (i = 0; i < LEN; i++) {
x->next = malloc(sizeof(*x));
x = x->next;
x->item = i;
x->next = NULL;
}
traverse(t);
traverse(rearranges(t));
return 0;
}
curr=head;
end=lastOfList;//last node if size of list is odd or last-1 node
for(int i=1;i<=listSize()/2;i++)
{
end->next=curr->next;
end=end->next;
end->next=null;
if(curr->next!=null)
if((curr->next)->next!=null)
curr->next=(curr->next)->next;
curr=curr->next;
}
You can implement a recursive solution where each call returns an updated node that will serve as the new next reference for the upper caller. We just have to go down the list until we find the last element, and then move every even node to the end of the list, and update the reference to the last element. Here's my solution (please try to do it yourself before looking at my and other solutions):
struct node {
int val;
struct node *next;
};
struct node *reorder_aux(struct node *l, int count, struct node **last);
struct node *reorder(struct node *l) {
struct node *x;
if (l == NULL)
return NULL;
return reorder_aux(l, 1, &x);
}
struct node *reorder_aux(struct node *l, int count, struct node **last) {
struct node *n;
if (l->next == NULL) {
*last = l;
return l;
}
n = reorder_aux(l->next, count+1, last);
if (count & 1) {
l->next = n;
return l;
}
else {
(*last)->next = l;
l->next = NULL;
*last = l;
return n;
}
}
At each step, if the current node l is an even node (as determined by count), then we append this node to the end, and tell the upper caller that its next pointer shall be updated to our next (because our next will be an odd node). In case we're an odd node, we just have to update our next pointer to whatever the recursive call returned (which will be a pointer to an odd node), and return the current node, since we will not move ourselves to the end of the list.
It's a nice exercise!
#include <stdio.h>
struct list {
struct list *next;
int ch;
};
void swap_odd_even (struct list **pp)
{
struct list *one, *two ;
for( ; (one = *pp) ; pp = &one->next) {
two = one->next;
if (!two) break;
*pp = two;
one->next = two->next;
two->next = one;
}
}
struct list arr[] =
{ {arr+1, 'A'} , {arr+2, 'B'} , {arr+3, 'C'} , {arr+4, 'D'}
, {arr+5, 'E'} , {arr+6, 'F'} , {arr+7, 'G'} , {arr+8, 'H'}
, {arr+9, 'I'} , {arr+10, 'J'} , {arr+11, 'K'} , {arr+12, 'L'}
, {arr+13, 'M'} , {arr+14, 'N'}, {arr+15, 'O'} , {arr+16, 'P'}
, {arr+17, 'Q'} , {arr+18, 'R'} , {arr+19, 'S'} , {arr+20, 'T'}
, {arr+21, 'U'} , {arr+22, 'V'}, {arr+23, 'W'} , {arr+24, 'X'}
, {arr+25, 'Y'} , {NULL, 'Z'} };
int main (void) {
struct list *root , *ptr;
root = arr;
for (ptr=root ; ptr; ptr = ptr->next ) {
printf( "-> %c" , ptr->ch );
}
printf( "\n" );
printf( "Swap\n" );
swap_odd_even ( &root);
for (ptr=root ; ptr; ptr = ptr->next ) {
printf( "-> %c" , ptr->ch );
}
printf( "\n" );
return 0;
}
In the following, every time swap_nodes is called another odd sinks to the last sunk odd. The evens are grouped together on each iteration and they bubble up to the end of the list. Here is an example:
/*
[0]-1-2-3-4-5
1-[0-2]-3-4-5
1-3-[0-2-4]-5
1-3-5-[0-2-4]
*/
#include <stdio.h>
#include <stdlib.h>
#define LIST_LENGTH 10
struct node{
int id;
struct node *next;
};
void print_list(struct node *current)
{
while(NULL != current){
printf("node id = %d\n",current->id);
current = current->next;
}
printf("Done\n");
}
struct node *swap_nodes(struct node *head_even, struct node *tail_even, struct node *next_odd)
{
tail_even->next = next_odd->next;
next_odd->next = head_even;
return next_odd;
}
struct node *reorder_list(struct node *head)
{
struct node *head_even;
struct node *tail_even;
struct node *next_odd;
struct node *last_odd;
if(NULL == head->next){
return head;
}
head_even = head;
tail_even = head;
next_odd = head->next;
last_odd = head->next;
head = swap_nodes(head_even, tail_even, next_odd);
if(NULL != tail_even->next){
tail_even = tail_even->next;
}
while (NULL != tail_even->next) {
next_odd = tail_even->next;
last_odd->next = swap_nodes(head_even, tail_even, next_odd);
last_odd = last_odd->next;
if(NULL != tail_even->next){
tail_even = tail_even->next;
}
}
return head;
}
int main(void)
{
int i;
struct node *head = (struct node *) malloc(LIST_LENGTH*sizeof(struct node));
struct node *mem = head;
if(NULL == head){
return -1;
}
struct node *current = head;
for(i=0;i<LIST_LENGTH-1;i++){
current->next = current + 1;
current->id = i;
current = current->next;
}
current->next = NULL;
current->id = i;
head = reorder_list(head);
print_list(head);
free(mem);
return 0;
}
I'm trying to append two structures into one
Ex.
l1 = add(1, add(2, NULL));
l2 = add(3, add(4, NULL));
myappend(l1,l2) = add(1,add(2,add(3,add(4,NULL))))
I tried many other ways that I can think of... but it doesn't work... can anyone help me out?
struct list_node {
struct list_node * rest;
int first;
};
list add(int in, list l) {
list r = malloc(sizeof(struct list_node));
r->first = in;
r->rest = l;
return r;
}
// My attempted solution;
list myappend(list l1,list l2){
list k = malloc(sizeof(struct list_node));
k=l2;
k=add(l1,k);
return k;
}
list myappend(list l1,list l2){
list k = l1;
while (k->rest != NULL)
{
k = k->rest;
}
k->rest = l2;
return l1;
}
Should work for you.
I guess the type list is struct list_node *. If you can define a type for list, you can define a type for list with a last point to the last node of the list, example:
struct list {
struct list_node *first;
struct list_node *last;
}
void myappend(struct list *l1,struct list *l2){
// check the argument here when needed.
l1->last->rest = l2->first;
l1->last = l2->last;
free(l2);
}
If you want to keep the type list as struct list_node *, you should
1) Ensure the last node(of a list)'s rest is NULL.
2) Loop and find the last node of the fist list and do the merge(just link them).
You can also use recursion code:
list __add(struct list_node *first_node, list rest) { // split your list_add()
first_node->rest = rest;
return first_node
}
list add(int in, list l) {
list r = malloc(sizeof(struct list_node));
r->rest = NULL;
r->first = in;
return __add(r, l);
}
list myappend(list l1,list l2){
if (l1)
return __add(l1, myappend(l1->rest, l2));
else
return l2;
}
Your solutions suffers of a number of problems.
Here you create a pointer to a list_node (that you call list)...
list k = malloc(sizeof(struct list_node));
... and then you throw that node away by overwriting that pointer with l2!
k=l2;
Here you pass l1 (a list) instead of an int, as a first argument.
k=add(l1,k);