学习 -周报
例题:#include<stdio.h>
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode* head = NULL, * tail = NULL;
int carry = 0;
while (l1 || l2) {
int n1 = l1 ? l1->val : 0;
int n2 = l2 ? l2->val : 0;
int sum = n1 + n2 + carry;
if (!head) {
head = tail = malloc(sizeof(struct ListNode));
//链表初始化时的 “头尾合一” 设计—— 因为此时链表还没有任何节点,
// 新创建的这一个节点既是 “第一个节点(头)”,也是 “最后一个节点(尾)”,
// 必须让 head 和 tail 同时指向它,才能后续正确管理链表。
tail->val = sum % 10;
tail->next = NULL;
}//进入循环的条件:head为空指针时
else {
tail->next = malloc(sizeof(struct ListNode));
tail->next->val = sum % 10;
tail = tail->next;
tail->next = NULL;
}
carry = sum / 10;//计算新的进位
if (l1) {
l1 = l1->next;
}//if(l1) 避免空指针,确保指针还有节点可走,l1=l1->next 让指针往下一个节点走
if (l2) {
l2 = l2->next;
}
}
if (carry > 0) {
tail->next = malloc(sizeof(struct ListNode));
tail->next->val = carry;//给新节点的next成员赋值carry.
tail->next->next = NULL;//给新节点的next成员赋值NULL
}//当carry>0时执行,tail->next给结果链表的“最后一个节点”,malloc 申请动态内存
return head;
1. 链表基础结构
struct ListNode {
int val;
struct ListNode *next;
};
知识点:
节点包含数据域(val)和指针域(next)
单向链表只能向前遍历
链表通过指针连接,内存不连续
2. 链表遍历技巧
while(l1 || l2) {
int n1 = l1 ? l1->val : 0; // 处理不等长链表
int n2 = l2 ? l2->val : 0;
// ...
if(l1) l1 = l1->next; // 移动指针
if(l2) l2 = l2->next;
}
知识点:
条件遍历:使用while(l1 || l2)处理长度不同的链表
空值处理:三元运算符处理空节点
指针移动:node = node->next遍历链表
3. 动态内存管理
// 创建新节点 head = tail = malloc(sizeof(struct ListNode)); tail->val = sum % 10; tail->next = NULL; // 添加后续节点 tail->next = malloc(sizeof(struct ListNode)); tail = tail->next; tail->next = NULL;
知识点:
malloc分配内存:动态创建节点
内存初始化:必须设置next指针为NULL
节点连接:通过指针链接形成链表
4. 头尾指针技术
struct ListNode* head = NULL, * tail = NULL;
知识点:
头指针(head):始终指向链表开头,用于返回结果
尾指针(tail):指向链表末尾,用于快速添加新节点
5. 进位处理算法
更多推荐

所有评论(0)