• 链表加法的两种实现


    第一种是高位在链表尾部
    a = 7->1->2
    b = 4->3
    result = 1->5->2

    没啥说的,注意进位,注意链表长度不一定一样
    #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("
    ");
    }
     
    /* Drier 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;
    }

    第二种是高位在链表头部
    a = 2 -> 1 -> 7 b = 3 -> 4 result = 2 -> 5 -> 1

    这个为了处理进位,需要用递归的思想
    // A recursive program to add two linked lists
    
    #include <stdio.h>
    #include <stdlib.h>
    
    // A linked List Node
    struct node
    {
        int data;
        struct node* next;
    };
    
    typedef struct node node;
    
    /* A utility function to insert a node at the beginning of linked list */
    void push(struct node** head_ref, int new_data)
    {
        /* allocate node */
        struct node* new_node = (struct node*) malloc(sizeof(struct node));
    
        /* put in the data  */
        new_node->data  = 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;
    }
    
    /* A utility function to print linked list */
    void printList(struct node *node)
    {
        while (node != NULL)
        {
            printf("%d  ", node->data);
            node = node->next;
        }
        printf("
    ");
    }
    
    // A utility function to swap two pointers
    void swapPointer( node** a, node** b )
    {
        node* t = *a;
        *a = *b;
        *b = t;
    }
    
    /* A utility function to get size of linked list */
    int getSize(struct node *node)
    {
        int size = 0;
        while (node != NULL)
        {
            node = node->next;
            size++;
        }
        return size;
    }
    
    // Adds two linked lists of same size represented by head1 and head2 and returns
    // head of the resultant linked list. Carry is propagated while returning from
    // the recursion
    node* addSameSize(node* head1, node* head2, int* carry)
    {
        // Since the function assumes linked lists are of same size,
        // check any of the two head pointers
        if (head1 == NULL)
            return NULL;
    
        int sum;
    
        // Allocate memory for sum node of current two nodes
        node* result = (node *)malloc(sizeof(node));
    
        // Recursively add remaining nodes and get the carry
        result->next = addSameSize(head1->next, head2->next, carry);
    
        // add digits of current nodes and propagated carry
        sum = head1->data + head2->data + *carry;
        *carry = sum / 10;
        sum = sum % 10;
    
        // Assigne the sum to current node of resultant list
        result->data = sum;
    
        return result;
    }
    
    // This function is called after the smaller list is added to the bigger
    // lists's sublist of same size.  Once the right sublist is added, the carry
    // must be added toe left side of larger list to get the final result.
    void addCarryToRemaining(node* head1, node* cur, int* carry, node** result)
    {
        int sum;
    
        // If diff. number of nodes are not traversed, add carry
        if (head1 != cur)
        {
            addCarryToRemaining(head1->next, cur, carry, result);
    
            sum = head1->data + *carry;
            *carry = sum/10;
            sum %= 10;
    
            // add this node to the front of the result
            push(result, sum);
        }
    }
    
    // The main function that adds two linked lists represented by head1 and head2.
    // The sum of two lists is stored in a list referred by result
    void addList(node* head1, node* head2, node** result)
    {
        node *cur;
    
        // first list is empty
        if (head1 == NULL)
        {
            *result = head2;
            return;
        }
    
        // second list is empty
        else if (head2 == NULL)
        {
            *result = head1;
            return;
        }
    
        int size1 = getSize(head1);
        int size2 = getSize(head2) ;
    
        int carry = 0;
    
        // Add same size lists
        if (size1 == size2)
            *result = addSameSize(head1, head2, &carry);
    
        else
        {
            int diff = abs(size1 - size2);
    
            // First list should always be larger than second list.
            // If not, swap pointers
            if (size1 < size2)
                swapPointer(&head1, &head2);
    
            // move diff. number of nodes in first list
            for (cur = head1; diff--; cur = cur->next);
    
            // get addition of same size lists
            *result = addSameSize(cur, head2, &carry);
    
            // get addition of remaining first list and carry
            addCarryToRemaining(head1, cur, &carry, result);
        }
    
        // if some carry is still there, add a new node to the fron of
        // the result list. e.g. 999 and 87
        if (carry)
            push(result, carry);
    }
    
    // Driver program to test above functions  
    int main()
    {
        node *head1 = NULL, *head2 = NULL, *result = NULL;
    
        int arr1[] = {9, 9, 9};
        int arr2[] = {1, 8};
    
        int size1 = sizeof(arr1) / sizeof(arr1[0]);
        int size2 = sizeof(arr2) / sizeof(arr2[0]);
    
        // Create first list as 9->9->9
        int i;
        for (i = size1-1; i >= 0; --i)
            push(&head1, arr1[i]);
    
        // Create second list as 1->8
        for (i = size2-1; i >= 0; --i)
            push(&head2, arr2[i]);
    
        addList(head1, head2, &result);
    
        printList(result);
        getchar();
        return 0;
    }
     
  • 相关阅读:
    位运算 & 网络序字节序
    TFTP & commons-net-3.3.jar
    存储过程
    poj1185-炮兵阵地(状态压缩dp)
    hdu4570-区间dp
    codevs1026-dp(记忆化搜索)
    hdu1494 跑跑卡丁车(动态规划)
    hdu5094-Maze
    hdu4403- A very hard Aoshu problem(搜索)
    hdu2510-符号三角形(dfs+打表)
  • 原文地址:https://www.cnblogs.com/yueyanglou/p/4915413.html
Copyright © 2020-2023  润新知