上个文章说要传二级指针,经过一段时间的学习之后才知道可以传一级指针:
之所以要传二级指针,是要改变一级指针的值,也就是把头节点的指针改变,如图:
从左边到右边,头指针 一级指针plist 的值发生改变所以要传二级指针。
首先,我们要搞明白一个事情:如果头指针不发生改变,只改变中间链表的成员,那是否可以只传一级指针呢?答案是:可以。
就拿plist后的第一个成员举例,我们创建了一个链表,plist指向了第一个成员的地址,也就是找到了第一个结构体(并非拷贝),当然可以改变第一个成员的元素,也就是可以从根本上改变这个链表成员的指向。
解决了这个问题,如果要求头指针改变应该怎么办,我们可以返回新的头指针,所以就有了以下代码:这两种的函数都能起到相同的作用。
struct stu* SeqListPushBack(stu* plist, StructType num);
//记得 return new_head
void SeqListPushBack(stu** plist, StructType num);
接下来是leedcote做题的感受:每次做 leetcode 都感觉自己像个傻子。
有些链表题的经验总结一下:
1.一个探路一个指路:
类似于这种简单删除的操作,需要验证pointer->number的值,根据真假来修改pointer_pre->next来修改链表的指向,通常会出现如下代码:
while(pointer==NULL){
pointer_pre=pointer;
pointer=pointer->next;
}
在上面的代码中,pointer_pre保存了pointer的值,接着pointer迭代一下。
2.一个指路一个记路:
如图所示,在翻转链表中,pointer 其实担任了指路和记路两个任务,因为 pointer->next 既要指向pointer_pre 同时也要遍历链表,但是 pointer->next 的值一旦改变就无法找到下一个链表成员,所以要先把链表成员的地址存起来,即 pointer_over=pointer->next,所以可能出现下面的代码:
第一行代码是先把三个指针安排好位置,然后反转链表指向,最后两行和第一行保证三个指针迭代向前一个单位。
struct ListNode* reverseList(struct ListNode* head){
struct ListNode*pointer=head,*pointer_over=head,*pointer_pre=NULL;
while(pointer_over!=NULL){
pointer_over=pointer->next;
pointer->next=pointer_pre;
pointer_pre=pointer;
pointer=pointer_over;
}
return pointer_pre;
}
做链表的题一定要考虑指针的移动逻辑和指向改变逻辑,确保两者不冲突的有序进行。
这就是文章的全部内容,希望对你有所帮助,如有错误欢迎讨论。