目录
题一:反转链表
思路一:
思路二:
题二:移除链表元素
思路一:
思路二:
题三:链表的中间节点
思路一:
题四:链表中倒数第k个结点
思路一:
题五:合并两个有序链表
思路一:
简化后:
本人实力有限可能对一些地方解释的不够清晰,可以自己尝试读代码,望海涵!
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
示例 1:
三个变量n1=NULL,n2=head,n3,如果n2不为NULL,则n3=n2->next,循环如果n2为NULL,就停下来,当n3为空时n3就不进行变化,最后n1会停在最后一个位置,这个时候逆置完成。
struct ListNode* reverseList(struct ListNode* head)
{
struct ListNode* n1,*n2,*n3;
n1 = NULL;
n2 = head;
if(n2)
n3 = n2->next;
while(n2)
{
n2->next = n1;
n1 = n2;
n2 = n3;
if(n3)
n3 = n3->next;
}
return n1;
}
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* newhead = NULL;
struct ListNode* cur = head;
while(cur)
{
struct ListNode* next = cur->next;
//头插新节点,更新头
cur->next = newhead;
newhead = cur;
cur = next;
}
return newhead;
}
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
分别定义结构体指针类型的n1=head,n2=NULL,在链表上进行n1->val == val,不同则不改变,相同则跳过这个结构体指针地址,指向下一个结构体的地址,然后free释放值相同的地址,循环操作到指向NULL地址,当然,如果第一个位置就与val相同,则,跳过这个地址,指向下一个地址。
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode* n1 = head, * n2 = NULL;
while (n1)
{
if (n1->val == val)
{
if (head == n1)
{
head = n1->next;
free(n1);
n1 = head;
}
else
{
n2->next = n1->next;
free(n1);
n1 = n2->next;
}
}
else
{
n2 = n1;
n1 = n1->next;
}
}
return head;
}
新开辟一个newnode,n1=head,n2=NULL;让原链表中与val不相同的位置放到新开辟的结构体指针中,依次放入,最后将newnode的最后一个地址的next==NULL,完成移除。
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode* n1 = head;
struct ListNode* newnode = NULL;
struct ListNode* n2 = NULL;
while (n1)
{
if (n1->val == val)
{
struct ListNode* tail = n1->next;
free(n1);
n1 = tail;
}
else
{
if (n2 == NULL)
{
n2 = n1;
newnode = n2;
}
else
{
n2->next = n1;
n2 = n2->next;
}
n1 = n1->next;
}
}
if (n2)
n2->next = NULL;
return newnode;
}
给你单链表的头结点 head
,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例 1:
分别定义快慢两个指针,快指针一次前进两个地址,慢指针一次前进一个地址,当奇数时快指针的next为NULL时,当链表为偶数时判断条件为地址为NULL,停下来,此时慢指针就在链表中间节点上。
struct ListNode* middleNode(struct ListNode* head)
{
struct ListNode* slow = head;
struct ListNode* fast = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
输入一个链表,输出该链表中倒数第k个结点。
分别定义快慢两个指针,快指针fast先前进k个地址,然后fast和slow开始同时每次前进一个地址,一直到fast的地址为NULL时,停下来,这时的slow就是倒数第k个节点。排除倒数第0个和传递的指针为NULL的两种情况,直接return NULL。
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k )
{
struct ListNode* fast = pListHead;
struct ListNode* slow = pListHead;
//方法一:
while(k--)
{
if(fast)
fast = fast->next;
else
return NULL;
}
//方法二:
//if (pListHead == NULL)
//{
// return NULL;
//}
//if (k == 0)
//{
// return NULL;
//}
//for (int i = 0; i < k; i++)
//{
// if (fast == NULL)
// {
// return NULL;
// }
// fast = fast->next;
//
//}
while(fast)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
创建一个新的结构体指针newnode=NULL,n1=list1,n2=list2,写一个tail=NUL来遍历newnode,先判断list1和list2是否为空,为空则返回另一方,均不为空则,则按如下图循环放入newnode,循环到有一方为NULL,做一个判断将另一方在newnode后接上。
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
if (list1 == NULL)
return list2;
if (list2 == NULL)
return list1;
struct ListNode* n1 = list1;
struct ListNode* n2 = list2;
struct ListNode* newnode = NULL;
struct ListNode* tail = NULL;
while(n1 && n2)
{
if(n1->val >= n2->val)
{
if(tail == NULL)
{
tail = n2;
newnode = tail;
n2 = n2->next;
}
else
{
tail->next = n2;
tail = tail->next;
n2 = n2->next;
}
}
else
{
if(tail == NULL)
{
tail = n1;
newnode = tail;
n1 = n1->next;
}
else
{
tail->next = n1;
tail = tail->next;
n1 = n1->next;
}
}
}
if(n1)
{
tail->next = n1;
}
if(n2)
{
else
tail->next = n2;
}
return newnode;
}
/*
解题思路:
此题可以先创建一个空链表,然后依次从两个有序链表中选取最小的进行尾插操作进行合并。
*/
typedef struct ListNode Node;
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if(l1 == NULL)
return l2;
else if(l2 == NULL)
return l1;
Node* head = NULL, *tail = NULL;
//创建空链表
head = tail = (Node*)malloc(sizeof(Node));
tail->next = NULL;
while(l1 && l2)
{
// 取小的进行尾插
if(l1->val < l2->val)
{
tail->next = l1;
tail = tail->next;
l1 = l1->next;
}
else
{
tail->next = l2;
tail = tail->next;
l2 = l2->next;
}
}
//剩余元素直接拼接
if(l1)
tail->next = l1;
else
tail->next = l2;
Node* list = head->next;
free(head);
return list;
}