Add two numbers represented by linked lists - cook the code

Tuesday, 7 November 2017

Add two numbers represented by linked lists

#include<stdio.h>
#include<stdlib.h>
/* Linked list node */
struct Node
{
    int data;
    struct Node* next;
};
/* Function to create a new node with given data */
struct Node *newNode(int data)
{
    struct Node *new_node = (struct Node *) malloc(sizeof(struct Node));
    new_node->data = data;
    new_node->next = NULL;
    return new_node;
}
/* Function to insert a node at the beginning of the Doubly Linked List */
void push(struct Node** head_ref, int new_data)
{
    /* allocate node */
    struct Node* new_node = newNode(new_data);
    /* link the old list off the new node */
    new_node->next = (*head_ref);
    /* move the head to point to the new node */
    (*head_ref)    = new_node;
}
/* Adds contents of two linked lists and return the head node of resultant list */
struct Node* addTwoLists (struct Node* first, struct Node* second)
{
    struct Node* res = NULL; // res is head node of the resultant list
    struct Node *temp, *prev = NULL;
    int carry = 0, sum;
    while (first != NULL || second != NULL) //while both lists exist
    {
        // Calculate value of next digit in resultant list.
        // The next digit is sum of following things
        // (i)  Carry
        // (ii) Next digit of first list (if there is a next digit)
        // (ii) Next digit of second list (if there is a next digit)
        sum = carry + (first? first->data: 0) + (second? second->data: 0);
        // update carry for next calulation
        carry = (sum >= 10)? 1 : 0;
        // update sum if it is greater than 10
        sum = sum % 10;
        // Create a new node with sum as data
        temp = newNode(sum);
        // if this is the first node then set it as head of the resultant list
        if(res == NULL)
            res = temp;
        else // If this is not the first node then connect it to the rest.
            prev->next = temp;
        // Set prev for next insertion
        prev  = temp;
        // Move first and second pointers to next nodes
        if (first) first = first->next;
        if (second) second = second->next;
    }
    if (carry > 0)
      temp->next = newNode(carry);
    // return head of the resultant list
    return res;
}
// A utility function to print a linked list
void printList(struct Node *node)
{
    while(node != NULL)
    {
        printf("%d ", node->data);
        node = node->next;
    }
    printf("\n");
}
/* Driver program to test above function */
int main(void)
{
    struct Node* res = NULL;
    struct Node* first = NULL;
    struct Node* second = NULL;
    // create first list 7->5->9->4->6
    push(&first, 6);
    push(&first, 4);
    push(&first, 9);
    push(&first, 5);
    push(&first, 7);
    printf("First List is ");
    printList(first);
    // create second list 8->4
    push(&second, 4);
    push(&second, 8);
    printf("Second List is ");
    printList(second);
    // Add the two lists and see result
    res = addTwoLists(first, second);
    printf("Resultant list is ");
    printList(res);
   return 0;
}


------------------------------------------------------------------------------------------



nt FindLength(Node* n) { // find the length of a given linked list.
	int ret = 0;
	while(n) {
		ret++;
		n = n->next;
	}
	return ret;
}
Node* Add(Node* list1, Node* list2) { // this function is called first
	int state = FindLength(list1) - FindLength(list2);
        // if state > 0, list1 is longer
        // if state < 0, list2 is longer
        // if state == 0, list1 and list2 is of same length
	int carry = 0;
	Node* ret = Add2(list1, list2, carry, state); // add the two lists	
	if ( carry > 0 ) { // handle carry for the leftmost digit
		Node* temp = new Node(carry);
		temp->next = ret;
		ret = temp;
	}
	return ret;
}
Node* Add2(Node* p1, Node* p2, int& carry, int state) { // helper function
	if ( p1 == NULL && p2 == NULL ) // if both are NULL, we are at the end
		return NULL;
	Node* ret = new Node(0); // create new node to return
	if ( state > 0 ) { // p1 is still longer than p2
                // only advance p1's pointer and decrease state
		ret->next = Add2(p1->next, p2, carry, state-1);
		ret->data = carry + p1->data; // just sum carry and p1's data
	}
	else if ( state < 0 ) { // p2 is still longer than p1
                // only advance p2's pointer and increase state
		ret->next = Add2(p1, p2->next, carry, state+1);
		ret->data = carry + p2->data; // just sum carry and p2's data.
	}
	else { // p1 and p2 are of same length
                // advance both pointers, state should stay untouched from now on(0).
		ret->next = Add2(p1->next, p2->next, carry, 0);
		ret->data = carry + p1->data + p2->data; // sum carry and both digits
	}
	carry = ret->data / 10; // calculate new carry
	ret->data %= 10;        // update the current data to be smaller than 10
	return ret;             // return the new node

}

No comments:

Post a Comment