前言 : 通过算法题 , 学习解决问题的思路 , 再面对类似的算法题时 , 能快速定位解决方案
一 . 移除链表元素
移除链表元素 : . - 力扣(LeetCode)
struct ListNode {
int val;
struct ListNode *next;
};
typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {
ListNode* newhead = NULL;
ListNode* newtail = NULL;
ListNode* pcur = head;
while (pcur)
{
//pcur的值为val时,进行尾插到新链表中
if (pcur->val != val)
{
//空链表
if (newhead == NULL)
{
newhead = pcur;
newtail = pcur;
}
//链表不为空
else {
newtail->next = pcur;
newtail = newtail->next;
}
}
pcur = pcur->next;
}
return newhead;
}
void test3()
{
//手动构造一个单链表
SLTNode* node1 = (SLTNode*)malloc(sizeof(SLTNode));
SLTNode* node2 = (SLTNode*)malloc(sizeof(SLTNode));
SLTNode* node3 = (SLTNode*)malloc(sizeof(SLTNode));
SLTNode* node4 = (SLTNode*)malloc(sizeof(SLTNode));
SLTNode* node5 = (SLTNode*)malloc(sizeof(SLTNode));
SLTNode* node6 = (SLTNode*)malloc(sizeof(SLTNode));
SLTNode* node7 = (SLTNode*)malloc(sizeof(SLTNode));
node1->data = 1;
node2->data = 2;
node3->data = 6;
node4->data = 3;
node5->data = 4;
node6->data = 5;
node7->data = 6;
node1->next = node2;
node2->next = node3;
node3->next = node4;
node4->next = node5;
node5->next = node6;
node6->next = node7;
node7->next = NULL;
SLTNode* plist = node1;
removeElements(plist, 6);
}
int main()
{
//test1();
//test2();
test3();
return 0;
}
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {
ListNode* newhead = NULL;
ListNode* newtail = NULL;
ListNode* pcur = head;
while(pcur)
{
//pcur的值为val时,进行尾插到新链表中
if(pcur->val != val)
{
//空链表
if(newhead == NULL)
{
newhead = pcur;
newtail = pcur;
}
//链表不为空
else{
newtail->next = pcur;
newtail = newtail->next;
}
}
pcur = pcur->next;
}
if(newtail)
newtail->next = NULL;
return newhead;
}
二 . 反转链表
反转链表:. - 力扣(LeetCode)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) {
if(head == NULL)
{
return head;
}
ListNode* n1,*n2,*n3;
n1 = NULL;
n2 = head;
n3 = head->next;
while(n2)
{
n2->next = n1 ;
n1 = n2 ;
n2 = n3 ;
if(n3)
n3 = n2->next;
}
return n1;
}
三 . 链表的中间结点
链表中间的结点 : . - 力扣(LeetCode)
注意 : 在循环条件的结束条件中 , && 操作符两边的操作数不可以互换位置!!!
因为会出现对空指针解引用 --> 报错 , 而(fast && fast->next) ,当fast为NULL时,短路,不会再继续判断下一个条件了
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
四 . 合并两个有序链表
合并两个有序链表: . - 力扣(LeetCode)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
if(list1 == NULL)
{
return list2;
}
if(list2 == NULL)
{
return list1;
}
ListNode* n1 = list1;
ListNode* n2 = list2;
ListNode* newhead ,*newtail;
newhead = newtail = NULL;
while(n1 && n2)
{
//n1 的值比较小,n1的值尾插
if(n1->val < n2->val)
{
//空链表
if(newhead == NULL)
{
newhead = n1;
newtail = n1;
}
//非空链表
else{
newtail->next = n1;
newtail = newtail->next;
}
n1 = n1->next;
}
//n2 的值比较小,n2的值尾插
else
{
//空链表
if(newhead == NULL)
{
newhead = n2;
newtail = n2;
}
//非空链表
else{
newtail->next = n2;
newtail = newtail->next;
}
n2 = n2->next;
}
}
if(n1)
{
newtail->next = n1;
}
if(n2)
{
newtail->next = n2;
}
return newhead;
}
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
if(list1 == NULL)
{
return list2;
}
if(list2 == NULL)
{
return list1;
}
ListNode* n1 = list1;
ListNode* n2 = list2;
ListNode* newhead ,*newtail;
newhead = newtail = (ListNode*)malloc(sizeof(ListNode));
while(n1 && n2)
{
//n1 的值比较小,n1的值尾插
if(n1->val < n2->val)
{
newtail->next = n1;
newtail = newtail->next;
n1 = n1->next;
}
//n2 的值比较小,n2的值尾插
else
{
newtail->next = n2;
newtail = newtail->next;
n2 = n2->next;
}
}
if(n1)
{
newtail->next = n1;
}
if(n2)
{
newtail->next = n2;
}
ListNode* rethead = newhead->next;
free(newhead);
newhead = NULL;
return rethead;
}
五 . 链表分割
链表分割 : 链表分割_牛客题霸_牛客网
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
#include <exception>
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
//创建两个非空链表 : 小链表,大链表
ListNode* lessHead, *lessTail;
lessHead = lessTail = (ListNode*)malloc(sizeof(ListNode));
ListNode* greaterHead, *greaterTail;
greaterHead = greaterTail = (ListNode*)malloc(sizeof(ListNode));
//遍历原链表,小于x 的尾插到小链表中,大于等于x 的尾插到大链表中
ListNode* pcur = pHead;
while (pcur) {
//小链表
if (pcur->val < x) {
lessTail->next = pcur;
lessTail = lessTail->next;
}
//大链表
else {
greaterTail->next = pcur;
greaterTail = greaterTail->next;
}
pcur = pcur->next;
}
//避免循环 --> 大链表的尾指针要置为NULL
greaterTail->next = NULL;
//大小链表首尾连接
lessTail->next = greaterHead->next;
ListNode* retHead = lessHead->next;
free(lessHead);
free(greaterHead);
lessHead = NULL;
greaterHead = NULL;
return retHead;
}
};