该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
#include
#include
/**
*
* 定义双向节点
* 数据区为一个整型数字
*
**/
struct Node {
int number;//数据区,仅一个数字,保存一位数字
struct Node * next;
struct Node * prev;
};
typedef struct Node Node;
/**
* 创建头节点
* param:number,此数字赋值给创建出的节点的数字区
* return:创建出来的头结点
*
*
**/
Node * create_head(int number){
Node * head = (Node *)malloc(sizeof(Node));
head->number = number;
//只有一个节点的时候,此节点的next和prev均为NULL
head->next = NULL;
head->prev = NULL;
return head;
}
/**
* 创建一个新的节点,并将此节点追加到链表的最末端
* param:**tail链表尾指针的指针,因为方法中需要修改尾指针,因为你懂的原因,这里使用了指针的指针
* number整型数字,赋值给新节点的数据区
**/
void create_node_to_tail(Node ** tail,int number){
//为新节点开辟空间
Node * node = (Node *)malloc(sizeof(Node));
node->number = number;
//因为新节点要加到尾部,所以它的next变为NULL,prev指向原有的尾部
node->next = NULL;
node->prev = *tail;
//原有的尾部的next指向最新的节点
(*tail)->next = node;
//新节点到链表尾部之后,新节点成为链表的尾部
*tail = node;
}
/**
* 创建一个新的节点,并将此节点追加到链表的最前端
* param**head链表头指针的指针,原因同上
* number同上
*
**/
void create_node_to_head(Node ** head,int number){
//为新节点开辟空间
Node * node = (Node *)malloc(sizeof(Node));
node->number = number;
//新节点加到头前面,所以它的prev变为NULL,next指向原有的头部
node->prev = NULL;
node->next = *head;
//原有的头部的prev指向最新的节点
(*head)->prev = node;
//最新的节点成为新的头部
*head = node;
}
/**
* 大数相加
* param:number1_head加数1的头指针
* number2_head加数2的头指针
* return:计算结果的尾指针,主要是为了方便输出
*
**/
Node * add_big(Node * number1_head,Node * number2_head){
//进位
int carry = 0;
Node * number1_current = number1_head;
Node * number2_current = number2_head;
//保存计算结果的链表的头指针和尾指针
Node * result_head = NULL;
Node * result_tail = NULL;
//循环时,只要有一个加数没有结束,则继续循环
while(number1_current != NULL || number2_current != NULL){
//加数1,如果节点为NULL,则此加数为0,应对两个加数不一样长的情况
int number1 = (number1_current == NULL)?0:number1_current->number;
//加数2,如果节点为NULL,则此加数为0,应对两个加数不一样长的情况
int number2 = (number2_current == NULL)?0:number2_current->number;
//计算加数1+加数2+进位
int result = number1 + number2 + carry;
//更新进位
carry = result/10;
//获取当前位除掉进位后的值
result = result % 10;
//如果尚未创建链表,说明当前是第一次进入循环,则创建头节点
if(result_head == NULL){
result_head = create_head(result);
result_tail = result_head;
}else{
//进入这里,说明链表已创建,可以直接创建新节点,并追加到原链表后面
create_node_to_tail(&result_tail,result);
}
//移动指针,进入下一次循环,加入非空判断,应对两个加数不一样长的情况
if(number1_current != NULL){
number1_current = number1_current->next;
}
if(number2_current != NULL){
number2_current = number2_current->next;
}
}
//结束循环后,如果进位大于0,则还需要再创建一个节点
if(carry > 0){
create_node_to_tail(&result_tail,carry);
}
//返回尾指针
return result_tail;
}
/**
* 输入大数
* return:输入后产生的链表的头指针
*
**/
Node * input_number(){
printf("%s","请输入加数\n");
//保存输入的数字的头指针和尾指针
Node * head = NULL;
Node * tail = NULL;
while(1){
//每次输入一个字符
char c;
scanf("%c",&c);
//0-9对应的asicc码值为48-57,在此范围内,说明输入的是数字
if(c >= 48 && c <= 57) {
//减去48,将char型转为数字
int number = c - 48;
//如果尚未创建链表,说明是第一次进入循环,则创建头节点
if(head == NULL){
head = create_head(number);
tail = head;
}else{
//进入到这里,说明链表已创建,可以直接创建新节点,并加到原链表的前面
//注:链表保存的数字,低位在前,高位在后,而输入数字时,高位先输入,低位后输入
//所以这里链表的结点要加到链表的最前面
create_node_to_head(&head,number);
}
}
//如果输入的是回车,则退出循环
else if(c == '\n'){
break;
}else{
//如果输入的不是上两者,则返回NULL
printf("%s","只可以输入数字\n");
return NULL;
}
}
return head;
}
/**
* 输出大数
* param:tail要输出的链表的尾指针,因为存放数据的时候,低位在前,高位在后,为了正常输出,需要从尾向头输出
*
**/
void output_number(Node * tail){
Node * current = tail;
//从尾到头,一个一个输出数字
while(current != NULL){
printf("%d",current->number);
current = current->prev;
}
}
void main(){
//依次输入加数,如果返回为NULL,则说明输入不合法,退出
Node * number1_head = input_number();
if(number1_head == NULL)
return;
Node * number2_head = input_number();
if(number2_head == NULL)
return;
//计算结果,并根据返回的尾指针输出数字
Node * result_tail = add_big(number1_head,number2_head);
output_number(result_tail);
}