链表介绍
基础概念:链表是一种数据的组织方式。其数据分散的存放在内存的不同位置,然后通过指针将这些数据串联在一起成为一个链状结构。其中数据跟指向下一个数据的指针构成链表的一个结点
/* 链表的一个节点Node */
class Node {
int m_data;
Node* m_next;
};
/* 链表 */
class singleLinkList {
Node* head; // 虚拟头结点,不存储内容,仅做头结点使用,因此该结点必定不为空
int lenth; // 链表的长度
};
链表操作
链表的常规操作包括创建跟删除链表,链表结点的增删改查等。
构造&析构函数:由于使用了虚拟头结点的方式,头结点不为空,因此需要在构造函数初始化头结点。
// 1. 构造函数
singleLinkList () {
head = new Node();
lenth = 0;
}
// 2. 析构函数
~singleLinkList () {
Node* cur = head->m_next;
head->m_next = NULL; // 先置空,避免异常访问
Node* p;
while (cur) {
p = cur->m_next;
delete cur;
cur = p;
}
delete head;
}
头插:往链表的头插入一个新的结点,注意在虚拟头结点之后
// 3. 头插
void headInsert(int data) {
Node* newNode = new Node(data);
newNode->m_next = head->m_next;
head->m_next = newNode;
lenth++;
}
尾插:往链表的末尾插入一个新的结点
// 4. 尾插
void tailInsert(int data) {
Node* newNode = new Node(data);
Node* p = head;
while (p->m_next) {
p = p->m_next;
}
p->m_next = newNode;
lenth++;
}
插入数据:链表的任意位置插入,但是需要有插入的规则
// 5. 任意位置插入
void insert(int data) {
Node* newNode = new Node(data);
Node* p = head;
while (p->m_next) {
if (data < p->m_data) { // 此时使用一个很简单的匹配规则
newNode->m_next = p->m_next;
p->m_next = newNode;
lenth++;
break;
}
p = p->m_next;
}
}
删除结点:
// 6. 删除
void remove(int data) {
Node* p = head;
while (p->m_next) {
if (p->m_next->m_data == data) {
p->m_next = p->m_next->m_next;
lenth--;
return;
}
p = p->m_next;
}
}
几个操作里面,其中插入跟删除操作可以结合查找操作来进行。比如先查找出某个结点,然后删除该结点。查找出某个结点,然后在该结点的之后插入一个结点。
示例代码
LeetCode练习题
- 移除链表元素
// 该题属于链表的基本操作,删除的结点。需要注意的是内存的释放
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* p = new ListNode(0, head);
ListNode* phead = p;
while (p && p->next) {
if (p->next->val == val) {
p->next = p->next->next;
/* 链表原结点是否未动态申请,是否需要释放。需要调整释放内存的位置
NodeList* cur = p->next;
delete cur;
*/
}else {
p = p->next;
}
}
ListNode* res = phead->next;
delete phead;
return res;
}
};
- 反转链表
// 对原链表不断使用头结点删除的同时,对新链表不断使用头插法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* res = nullptr;
ListNode* temp = nullptr;
while (head) {
temp = head->next;
head->next = res;
res = head;
head = temp;
}
return res;
}
};
扩展:
有序链表,循环链表,双向链表等。