Monday, December 12, 2011

Add/Subtract Long positive numbers in Linked Lists

Add/Subtract two long positive numbers represented by two linked lists.
1.AddList()
2.SubtractList()

Using Extra Space:
http://www.programcreek.com/2012/12/add-two-numbers/
http://www.geeksforgeeks.org/add-two-numbers-represented-by-linked-lists/
Without using Extra Space:
http://www.geeksforgeeks.org/sum-of-two-linked-lists/
Subtract Lists:
http://www.geeksforgeeks.org/subtract-two-numbers-represented-as-linked-lists/

http://algorithms.tutorialhorizon.com/add-two-numbers-represented-by-a-linked-list-numbers-are-stored-in-reverse-order/
http://algorithms.tutorialhorizon.com/add-two-numbers-represented-by-a-linked-list-numbers-are-stored-in-forward-order/

Add Lists:
Method 1:Reversing the List

Program 1:
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

struct node
{
    int data;
    struct node* next;
};


static void reverse(struct node** head_ref)
{
    struct node* prev = NULL;
    struct node* current = *head_ref;
    struct node* next;
    while (current != NULL)
    {
        next = current->next;
        current->next = prev;
        prev = current;
        current = next;
    }
    *head_ref = prev;
}


void push(struct node** head_ref, int new_data)
{
    struct node* new_node =
        (struct node*) malloc(sizeof(struct node));

    new_node->data = new_data;

    new_node->next = (*head_ref);

    (*head_ref) = new_node;
}

struct node* addition (struct node* temp1, struct node* temp2)
{

    struct node* prev = NULL;
    int carry = 0,a,b,result;

    while (temp1 || temp2) //while both lists exist
    {

        if(temp1) a=temp1->data;
        else a=0;

        if(temp2) b=temp2->data;
        else b=0;

        result = carry;
        if(temp1)
            result+=temp1->data;
        if(temp2)
            result+=temp2->data;

        carry=result/10;

        struct node * newnode = (struct node*) malloc (sizeof(struct node));
        newnode->data=(result)%10;
        newnode->next = prev;

        prev=newnode;
        if(temp1)
            temp1=temp1->next;
        if(temp2)
            temp2=temp2->next;
    }
    return prev;

}

void printList(struct node *node)
{
    while(node != NULL)
    {
        printf("%d ", node->data);
        node = node->next;
    }
}

int main(void)
{
    struct node* head = NULL;
    struct node* head1 = NULL;
    struct node* head2 = NULL;

    /* Created Linked list is 1->2->3->4->5->6->7->8 */

    push(&head1, 4);
    push(&head1, 3);
    push(&head1, 2);
    push(&head1, 1);
    printf("list 1 is \t");
    printList(head1);
    printf("\n");
    reverse(&head1);

    push(&head2, 6);
    push(&head2, 5);
    push(&head2, 4);
    printf("list 2 is \t");
    printList(head2);
    printf("\n");
    reverse(&head2);

    head=addition(head1,head2);

    printf("resultant list is   ");

    printList(head);
    printf("\n");
    getchar();
    return(0);
}

Program 2:

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {

    unsigned char c;
    struct Node *next;

}Node;

typedef Node* slist;

slist reverse(slist);
Node *makeNode(unsigned char);


slist Sum(slist left, slist right) {

    if(!left || !right) {
        return left ? left : right;
    }

    left = reverse(left);
    right = reverse(right);

    unsigned char carry = left->c + right->c;

    slist ret = makeNode(carry % 10);
    carry /= 10;


    Node *p = left->next;
    Node *q = right->next;
    Node *r = ret;

    while(p || q) {

        carry += (p? p->c : 0)  + (q ? q->c : 0);

        r->next = makeNode(carry % 10);
        carry /= 10;

        r = r->next;
        p = p ? p->next : NULL;
        q = q ? q->next : NULL;
    }

    if(carry)
        r->next = makeNode(1);

    reverse(left);
    reverse(right);

    return reverse(ret);

}

slist reverse(slist s) {

    if(s->next == NULL)
        return s;

    Node *ret = reverse(s->next);

    s->next->next = s;
    s->next = NULL;

    return ret;
}

Node *makeNode(unsigned char c) {

    Node * tmp = (slist)calloc(sizeof(Node), 1);

    tmp->c = c;

    return tmp;

}


void print(slist s) {

    if(s == NULL) {
        printf("\n");
        return;
    }
    printf("%c", s->c + '0');

    print(s->next);
}


slist listFromString(const char *s) {

    if(!s || !*s) return NULL;

    slist ret = makeNode(*s++ - '0');

    Node *tmp = ret;

    unsigned char c;

    while((c = *s++)) {
        tmp->next = makeNode(c - '0');
        tmp = tmp->next;
    }

    return ret;
}

int main()
{
    slist left  = listFromString("99");
    slist right  = listFromString("233823");

    slist sum = Sum(left, right);

    print(sum);
    getchar();
    return 0;
}

Method 2:

 Take two stacks and push a linked list to a stack. After done pushing, simply start popping the stacks, add the numbers, get the carry over, generate another node with the result and add to front to a new linked list.

No comments:

Post a Comment