有符号大数的加减链表实现C语言
时间: 2023-07-11 20:37:43 浏览: 97
用链表实现大数相加减.doc
以下是有符号大数的加减链表实现的 C 语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
/* 定义链表节点 */
typedef struct ListNode {
int val;
struct ListNode* next;
} ListNode;
/* 反转链表 */
ListNode* reverseList(ListNode* head) {
ListNode* prev = NULL;
ListNode* curr = head;
while (curr) {
ListNode* next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
/* 删除链表头部的 0 */
ListNode* trimZero(ListNode* head) {
while (head && head->val == 0) {
ListNode* tmp = head;
head = head->next;
free(tmp);
}
return head;
}
/* 创建链表节点 */
ListNode* createNode(int val) {
ListNode* node = (ListNode*)malloc(sizeof(ListNode));
node->val = val;
node->next = NULL;
return node;
}
/* 将数组转换为链表 */
ListNode* arrayToList(int* arr, int len) {
ListNode* dummy = createNode(-1);
ListNode* tail = dummy;
for (int i = 0; i < len; i++) {
ListNode* node = createNode(arr[i]);
tail->next = node;
tail = node;
}
return dummy->next;
}
/* 将链表转换为数组,并返回数组长度 */
int* listToArray(ListNode* head, int* len) {
ListNode* curr = head;
int count = 0;
while (curr) {
count++;
curr = curr->next;
}
int* arr = (int*)malloc(sizeof(int) * count);
curr = head;
for (int i = 0; i < count; i++) {
arr[i] = curr ? curr->val : 0;
curr = curr ? curr->next : NULL;
}
*len = count;
return arr;
}
/* 对链表进行加法运算 */
ListNode* add(ListNode* l1, ListNode* l2) {
ListNode* dummy = createNode(-1);
ListNode* tail = dummy;
int carry = 0;
while (l1 || l2) {
int sum = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry;
carry = sum / 10;
ListNode* node = createNode(sum % 10);
tail->next = node;
tail = node;
l1 = l1 ? l1->next : NULL;
l2 = l2 ? l2->next : NULL;
}
if (carry) {
ListNode* node = createNode(carry);
tail->next = node;
tail = node;
}
return dummy->next;
}
/* 对链表进行减法运算 */
ListNode* subtract(ListNode* l1, ListNode* l2) {
ListNode* dummy = createNode(-1);
ListNode* tail = dummy;
int borrow = 0;
while (l1 || l2) {
int diff = (l1 ? l1->val : 0) - (l2 ? l2->val : 0) - borrow;
if (diff < 0) {
diff += 10;
borrow = 1;
} else {
borrow = 0;
}
ListNode* node = createNode(diff);
tail->next = node;
tail = node;
l1 = l1 ? l1->next : NULL;
l2 = l2 ? l2->next : NULL;
}
return dummy->next;
}
/* 对有符号大数进行加法运算 */
ListNode* addBigNumber(ListNode* l1, ListNode* l2) {
// 处理符号位
int sign1 = l1->val < 0 ? -1 : 1;
int sign2 = l2->val < 0 ? -1 : 1;
if (sign1 * sign2 == 1) {
// 同号相加
l1->val = abs(l1->val);
l2->val = abs(l2->val);
ListNode* result = add(l1, l2);
result = trimZero(result);
if (result == NULL) {
result = createNode(0);
}
result->val *= sign1;
return result;
} else {
// 异号相减
l1->val = abs(l1->val);
l2->val = abs(l2->val);
ListNode* result = NULL;
if (sign1 == -1) { // l1 < 0, l2 > 0
result = subtract(l2, l1);
} else { // l1 > 0, l2 < 0
result = subtract(l1, l2);
}
result = trimZero(result);
if (result == NULL) {
result = createNode(0);
}
result->val *= sign1;
return result;
}
}
/* 主函数 */
int main() {
int a[] = {1, 2, 3, 4, -5, 6, 7, 8, 9};
int b[] = {9, 8, 7, -6, 5, 4, 3, 2, 1, 0};
int len1 = sizeof(a) / sizeof(int);
int len2 = sizeof(b) / sizeof(int);
ListNode* l1 = arrayToList(a, len1);
ListNode* l2 = arrayToList(b, len2);
ListNode* result = addBigNumber(l1, l2);
int len = 0;
int* arr = listToArray(result, &len);
printf("Result: ");
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr);
return 0;
}
```
该代码实现了对有符号大数进行加减法运算的功能。其中,每一个链表节点表示一个数字(可能为正数或负数),符号位存储在链表头节点中。函数 `add` 和 `subtract` 分别实现了链表的加法和减法运算,函数 `addBigNumber` 判断两个数字的符号后,调用 `add` 或 `subtract` 进行相应的运算。最后,我们将结果从链表转换为数组并输出。
阅读全文