目录
链表的中间节点
思路1:先遍历一遍算出总的节点数量
然后在遍历找 总节点的一半的那个节点(既中间节点)
实现代码
struct ListNode* middleNode(struct ListNode* head){
int Listlen = 0;
struct ListNode* cur = head;
while(cur)//遍历计算出Listlen
{
cur = cur->next;
Listlen++;
}
struct ListNode* mid = head;
int newlen = Listlen/2;
while(newlen--)
{
mid = mid->next;
}
return mid;
}
思路2:快慢指针
快指针走2步,慢指针走1步(只需要遍历一遍链表)
实现代码
struct ListNode* middleNode(struct ListNode* head){
if(head->next == NULL)
return head;
struct ListNode* slow = head;
struct ListNode* fast = head;
while(fast && fast->next)//偶数,奇数 循环终止条件(为NULL)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
链表中倒数第K个节点
思路1:倒数第K个既为正数的链表长度(n)-k个
实现代码
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
if(pListHead == NULL)
return NULL;
struct ListNode* cur = pListHead;
int Listlen = 0;
while(cur)
{
cur = cur->next;
Listlen++;
}
int n = Listlen-k;
if(n < 0)
return NULL;
struct ListNode* find = pListHead;
while(n--)
{
find = find->next;
}
return find;
}
思路二:快慢指针
先让快指针走K步,然后快慢指针一起走
实现代码
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
struct ListNode* fast = pListHead;
struct ListNode* slow = pListHead;
//先让fast走k步
int n = 0;
while(pListHead)
{
pListHead = pListHead->next;
n++;
}
if(k > n)//倒数第K个大于链表长度时,直接返回
return NULL;
while(k--)
{
fast = fast->next;
}
while(fast)
{
fast = fast->next;
slow = slow->next;
}
return slow;
// write code here
}
合并两个有序链表
思路:取小尾插
创建一个头节点,去小的尾插上去
实现代码
//创建一个带头节点
struct ListNode* head = NULL;
struct ListNode*tail =NULL;
tail=head =(struct ListNode*)malloc(sizeof(struct ListNode));
tail->next = NULL;
while(l1 && l2)//有一个为空循环就结束
{
if(l1->val < l2->val)//取小的尾插
{
tail->next = l1;
l1 = l1->next;
}
else
{
tail->next = l2;
l2 = l2->next;
}
tail = tail->next;
}
//出循环可能是l1或者l2 为空
if(l1 == NULL)//l2比l1长 l1为空把l2剩余部分尾插上去
{
tail->next = l2;
}
if(l2 == NULL)
{
tail->next = l1;
}
struct ListNode* newhead = head;
newhead = newhead->next;
free(head);
return newhead;
}