有一个节点, 它含有两个值, 一个是当前他代表的值, 一个是指向的下一个值
the interface
过程解析
1️⃣ add node内部直接剪切出来
int main() {
Node* head = NULL;
int number;
do {
scanf("%d", &number);
if (number != -1) {
node_add(head, number);
}
} while (number != -1);
return 0;
}
void node_add(Node *head, int number){
// add a new node
Node *p=(Node*)malloc(sizeof(Node));
/* 既然要一个node存放新值, 为什么不直接Node p呢?
因为我到时候是需要原最后node去指向新node的地址, 这样简洁, 真是这样吗?
这是个本地变量, 不用malloc, node存不下来 */
p->value=number;
p->next=NULL;
// find the last node
if(!head){
/* 如果是NULL, 那第一个就得是head */
head=p;
}else{
Node *last=head;
while(last->next){
last=last->next;
}
/* 会不会觉得这里每次add找last都挺烦的? 不要担心, 是个伏笔 */
// attach
last->next=p;
}
}
❓ 为什么head进去里头改变值了外面没改变?
- 我传进去的是地址没错, 但是我没有溯源去改这个地址上的变量, 而是直接改了这个地址, 这种情况地址就是个变量(事实上也确实只是个变量而已), 那么自然不会变
2️⃣ 在链表中找到数字并删除
int main() {
List list;
list.head = NULL;
int number;
do {
scanf("%d", &number);
if (number != -1) {
node_add(&list, number);
}
} while (number != -1);
scanf("%d", &number);
Node *p, *q = NULL;
/* q用来记录前一个node的地址 */
int isfound = 0;
for (p = list.head; p; q = p, p = p->next) {
if (p->value == number) {
if (!p->next) { // 特殊情况是number就是第一个数
list.head = p->next; // 注意第一个head要改咯
} else {
q->next = p->next;
}
free(p);
isfound = 1;
break;
}
}
if (!isfound) {
printf("没找到");
}
return 0;
}
❓ How do we find the boundary?
- Any pointer at the left of
->
must be checked
3️⃣ 清除链表
Node *p = list.head, *q;
while (p) {
q = p->next; // 收起那质朴的想法, 这样可以免去q的初值, 而且还能化简
free(p);
p = q;
// q=q->next;
}
Node *p, *q;
for (p = list.head; p; p = q) {
q = p->next;
free(p);
}
for
循环的条件还是有玩头的