提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
数组结束,开始链表
一、移除链表元素
- 遍历链表,删除指定元素值
- 使用虚拟头节点,记录前一个位置,更改指针指向
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//虚拟头节点
if (head == nullptr) return NULL;
ListNode *dummyNode = new ListNode(0);
dummyNode->next = head;
ListNode *cur = dummyNode;
//遍历链表查找节点,如果符合条件就删除
while (head != nullptr) {
if (head->val == val) {
cur->next = head->next;
head = head->next;
}
else {
head = head->next;
cur = cur->next;
}
}
return dummyNode->next;
}
};
二、设计链表
有些难度,实现代码没问题,细节问题还需要完善
class MyLinkedList {
public:
struct ListNode {
int val;
ListNode *next;
ListNode (int val) : val(val), next(nullptr) {}
};
MyLinkedList() {
size = 0;
dummyNode = new ListNode(0);
}
int get(int index) {
if (index < 0 || index > (size - 1)) {
return -1;
}
ListNode* cur = dummyNode->next; //真正的头节点
while (index --) {
cur = cur->next;
}
return cur->val;
}
void addAtHead(int val) {
//插入到第一个元素之前
ListNode* cur = new ListNode(val);
cur->next = dummyNode->next;
dummyNode->next = cur;
size++;
}
void addAtTail(int val) {
//插入到最后一个位置
ListNode* cur = dummyNode;
while (cur->next != nullptr) {
cur = cur->next;
}
ListNode* node = new ListNode(val);
cur->next = node;
size++;
}
void addAtIndex(int index, int val) { //没错
//插入到指定下标之前
if(index > size) return;
if(index < 0) index = 0;
ListNode* newNode = new ListNode(val);
ListNode* cur = dummyNode;
while(index--) {
cur = cur->next;
}
newNode->next = cur->next;
cur->next = newNode;
size++;
}
void deleteAtIndex(int index) {
if (index < 0 || index >= size) return;
ListNode* cur = dummyNode;
while (index--) {
cur = cur->next;
}
cur->next = cur->next->next;
size--;
}
private:
int size;
ListNode* dummyNode;
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/
三、反转链表
简单思路就是重新尾插,双指针,一个指向节点,一个指向前一个结点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//反转整个链表
//整体思路就是尾插法,重新插入
if (head == nullptr) return head;
ListNode* dummyNode = new ListNode(0);
dummyNode->next = head;
ListNode* cur = dummyNode->next;
ListNode* pre = nullptr;
while (cur != nullptr) {
ListNode* node = cur->next;
cur->next = pre;
pre = cur;
cur = node;
}
return pre;
}
};
总结
链表内容有些生疏,但操作大差不差,这几天多多练习。加油!