使用链表计算两个大整数的和
一道有意思的编程练习题:
两个单链表(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
Date: 2013.06.30
HTML generated by org-mode 6.35i in emacs 24