• 使用链表计算两个大整数的和


    使用链表计算两个大整数的和

    一道有意思的编程练习题:

    两个单链表(singly linked list),每一个节点里面一个0-9的数字,输入就相当于两个大数了。然后返回这两个数的和(一个新list)。这两个输入的list长度相等。 要求是:1. 不用递归。2. 要求算法在最好的情况下,只遍历两个list一次 ,最差的情况下两遍。

    下面是我的解法:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define MAX 32 // 列表长度
    
    struct Node {
        char num;
        struct Node *next;
    };
    
    void list_build(struct Node **list);
    void list_add(struct Node *list1, struct Node *list2, struct Node **sum);
    void list_print(struct Node *list);
    void list_free(struct Node *list);
    
    int main(int argc, char *argv[])
    {
        int i;
        struct Node *list1;
        struct Node *list2;
        struct Node *sum;
    
        // 随机函数初始化
        srand((unsigned int)time(NULL));
    
        for(i = 0; i < 100; i++) {
            // 将三个列表初始化为空
            list1 = list2 = sum = NULL;
    
            // 构建链表
            list_build(&list1);
            list_build(&list2);
    
            // 链表相加
            list_add(list1, list2, &sum);
    
            // 格式化输出
            list_print(list1); printf(" + ");
            list_print(list2); printf(" == ");
            list_print(sum);
            printf("
    ");
    
            // 释放分配的heap空间
            list_free(list1);
            list_free(list2);
            list_free(sum);
        }
    
        system("pause"); 
        return 0;
    }
    
    // 头部插入一个元素
    struct Node * insert(struct Node *list, struct Node *node)
    {
        struct Node *swap;
        swap = list;
        list = node;
        list->next = swap;
    
        return list;
    }
    
    // 使用随机数生成一个链表
    void list_build(struct Node **list)
    {
        int i;
        struct Node *node;
    
        *list = NULL;
    
        for(i = 0; i < MAX; i++) {
            node = (struct Node *)malloc(sizeof(struct Node));
    
            node->num = rand() % 10;
            node->next = NULL;
    
            if(*list == NULL ) {
                *list = node;
            }
            else {
                *list = insert(*list, node);
            }
        }
    
        if(*list) {
            while((*list)->num == 0) {
                (*list)->num = rand() % 10;
            }
        }
    }
    
    // 执行两个链表的加法,结果放在sum链表中
    void list_add(struct Node *list1, struct Node *list2, struct Node **sum)
    {
        int flag;
    
        struct Node *sump = NULL;
        struct Node *temp = NULL;
    
        while(list1) {
    
            temp = (struct Node *)malloc(sizeof(struct Node));
    
            temp->num = list1->num + list2->num;
            temp->next = NULL;
    
            if(sump == NULL) {
                sump = temp;
            }
            else {
                sump = insert(sump, temp);
            }
    
            list1 = list1->next;
            list2 = list2->next;
        }
    
        *sum = NULL;
        flag = 0;
    
        while(sump) {
            sump->num = sump->num + flag;
            flag = (sump->num >= 10) ? 1 : 0;
            sump->num = flag ? (sump->num - 10) : (sump->num);
            temp = sump;
            sump = sump->next;
            temp->next = NULL;
    
            if(*sum == NULL) {
                *sum = temp;
            }
            else {
                *sum = insert(*sum, temp);
            }
        }
    
        if(flag) {
            temp = (struct Node *)malloc(sizeof(struct Node));
            temp->num = flag;
            temp->next = NULL;
            *sum = insert(*sum, temp);
        }
    }
    
    // 查看结果
    void list_print(struct Node *list)
    {
        while(list) {
            printf("%d", list->num);
            list = list->next;
        }
    }
    
    // 释放空间
    void list_free(struct Node *list)
    {
        struct Node *temp;
        while(list) {
            temp = list;
            temp->next = NULL;
            list = list->next;
            free(temp);
        }
    }
    

    只找到了使用两次遍历的方法,使用一次遍历的方法见:link

    Author: wangsd

    Date: 2013.06.30

    HTML generated by org-mode 6.35i in emacs 24

  • 相关阅读:
    二叉树 排序二叉树-可以通过中序遍历得到排序的数据 二叉排序树时间复杂度O(logn),
    双链表排序
    Linux C 单链表 读取文件 并排序 实例并解释
    Linux 中文乱码问题
    双向链表排序
    玩转iOS开发
    Firefox OS简单介绍
    深入理解Dalvik虚拟机- 解释器的执行机制
    菜鸟学Struts——I18N对国际化的支持
    【leetcode】Flatten Binary Tree to Linked List
  • 原文地址:https://www.cnblogs.com/wangshide/p/3164041.html
Copyright © 2020-2023  润新知