在数据结构的学习时,我们一定要注意练习,练习,再练习!!会独立思考,写出代码才是最终目标!!
1.链表的反转
链表反转OJ
链表反转方式有多种,这里我们讲解一种相对简单的方法,并且时间复杂度为O(N)的方法
那么思路是什么呢?
…
这种方法我们称为迭代法,这里我们就是通过使用三个指针n1,n2,n3来从后指向前。
三个指针分别指向NULL , 头节点,和头节点的下一个节点
然后我们怎么移动呢?
首先我们需要先将n2->next = n1
n1 = n2
n2 = n3
n3 = n3->next
这里实现掉头的就是n2->next = n1这一句
那么 最后我们这里的暂停条件是什么呢?
最后这里n3走到了空,但是我们最主要的是n2->next = n1这一句,所以n3等于空的时候我们还是需要进入循环,但是这里如果盲目进入那么这里就会出现错误。具体在哪里呢?
来展示一下我们的代码
struct ListNode* reverseList(struct ListNode* head) {
if(head==NULL)
return NULL;
struct ListNode* n1 = NULL;
struct ListNode* n2 = head;
struct ListNode* n3 = head->next;
while(n2)
{
n2->next = n1;
n1 = n2;
n2 = n3;
n3 = n3->next;
}
return n1;
}
大家来看一下如果这里我们直接进入这个while循环,我们走到while虚幻中第四条语句的时候会发现,这里有一个对n3的解引用,那么我们可以对空指针进行解引用吗?答案是当然不行所以我们这里需要加个if判断一下。
下面才是正确的代码
struct ListNode* reverseList(struct ListNode* head) {
if(head==NULL)
return NULL;
struct ListNode* n1 = NULL;
struct ListNode* n2 = head;
struct ListNode* n3 = head->next;
while(n2)
{
n2->next = n1;
n1 = n2;
n2 = n3;
if(n3!=NULL) //这里我们加个判断,如果n3走到了空这里我们就不用解引用了
n3 = n3->next;
}
return n1;
}
大家学会了就快去上面的链接练习一下吧,我们接着讲第二个链表的经典题目,叫做寻找链表中间节点。
2.链表的中间节点
链表的中间节点OJ
链表的中间节点这个题目就相对简单许多了
这里我们只需要理解一个东西就行了,只需要采用快慢指针的方式来就可以完美解决
这里我们将快慢两个指针同时指向头节点,只需要让慢指针一次走一步,快指针一次走两步,这样我们就有个二倍的关系,就可以轻松找出中间节点啦。
这里注意题目说明如果是偶数个节点我们返回第二个节点
所以这个题目就很简单啦
接下来我们代码实现一下
struct ListNode* middleNode(struct ListNode* head) {
struct ListNode* fast = head;
struct ListNode* slow = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
这样这个代码就完成啦,大家快去练习吧!!