1.移除链表元素
题目链接:203. 移除链表元素 - 力扣(LeetCode)
思路分析:
思路1:我们可以遍历链表,找到要删除的数据,并将该节点free掉就行了。不过该思路有点复杂,因为我们在移除一个节点的时候,我们还要找到要移除节点的前一个节点。
思路2:创建一个新的链表。
我们可以创建一个新的链表,通过遍历原链表,将不是要移除的节点尾插到新的链表就行了。
代码实现
typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {
//创建新链表
ListNode*newhead,*newtail;
newhead=newtail=NULL;
//遍历原链表
ListNode*pcur=head;
while(pcur)
{
if(pcur->val!=val)
{
//新链表为空
if(newhead==NULL)
{
newhead=newtail=pcur;
}
else
{
//新链表不为空
newtail->next=pcur;
newtail=pcur;
}
}
pcur=pcur->next;
}
if(newtail)
{
newtail->next=NULL;
}
return newhead;
}
注意事项,最后我们要将newtail的next置为NULL。
2.反转链表
思路1:暴力反转法。
我们通过一个创建一个prev,通过不断的变换达成暴力翻转链表。
代码实现
typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) {
ListNode*prev=NULL;
ListNode*pcur=head;
while(pcur)
{
ListNode*next=pcur->next;
pcur->next=prev;
prev=pcur;
pcur=next;
}
return prev;
}
注意事项:由于最后我们要将pcur向pcur->next的位置移动,但是前面的pcur->next已经发生改变,所以我们要提前将pcur->next的内容存储起来。
思路2:创建三个指针
这个方法就很牛逼了,相对于前面的暴力反转,其比较好理解。
我们建立3个指针,第一个指针置为NULL,第二个指针指向head,第三个指针指向head->next,
如上图所示,我们通过n1,n2,n3的不断1变换,来实现n2->next指向n1。直到n2为空。
typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) {
//判空
if(head==NULL)
{
return NULL;
}
ListNode*n1,*n2,*n3;
n1=NULL;
n2=head;
n3=head->next;
while(n2)
{
n2->next=n1;
n1=n2;
n2=n3;
if(n3){
n3=n3->next;
}
}
return n1;
}