mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 00:43:04 +08:00
Merge pull request #2603 from ForsakenDelusion/master
更新0707.设计链表 新增CPP版本的双链表
This commit is contained in:
@ -165,6 +165,140 @@ private:
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
### C++双链表法:
|
||||
|
||||
```CPP
|
||||
//采用循环虚拟结点的双链表实现
|
||||
class MyLinkedList {
|
||||
public:
|
||||
// 定义双向链表节点结构体
|
||||
struct DList {
|
||||
int elem; // 节点存储的元素
|
||||
DList *next; // 指向下一个节点的指针
|
||||
DList *prev; // 指向上一个节点的指针
|
||||
// 构造函数,创建一个值为elem的新节点
|
||||
DList(int elem) : elem(elem), next(nullptr), prev(nullptr) {};
|
||||
};
|
||||
|
||||
// 构造函数,初始化链表
|
||||
MyLinkedList() {
|
||||
sentinelNode = new DList(0); // 创建哨兵节点,不存储有效数据
|
||||
sentinelNode->next = sentinelNode; // 哨兵节点的下一个节点指向自身,形成循环
|
||||
sentinelNode->prev = sentinelNode; // 哨兵节点的上一个节点指向自身,形成循环
|
||||
size = 0; // 初始化链表大小为0
|
||||
}
|
||||
|
||||
// 获取链表中第index个节点的值
|
||||
int get(int index) {
|
||||
if (index > (size - 1) || index < 0) { // 检查索引是否超出范围
|
||||
return -1; // 如果超出范围,返回-1
|
||||
}
|
||||
int num;
|
||||
int mid = size >> 1; // 计算链表中部位置
|
||||
DList *curNode = sentinelNode; // 从哨兵节点开始
|
||||
if (index < mid) { // 如果索引小于中部位置,从前往后遍历
|
||||
for (int i = 0; i < index + 1; i++) {
|
||||
curNode = curNode->next; // 移动到目标节点
|
||||
}
|
||||
} else { // 如果索引大于等于中部位置,从后往前遍历
|
||||
for (int i = 0; i < size - index; i++) {
|
||||
curNode = curNode->prev; // 移动到目标节点
|
||||
}
|
||||
}
|
||||
num = curNode->elem; // 获取目标节点的值
|
||||
return num; // 返回节点的值
|
||||
}
|
||||
|
||||
// 在链表头部添加节点
|
||||
void addAtHead(int val) {
|
||||
DList *newNode = new DList(val); // 创建新节点
|
||||
DList *next = sentinelNode->next; // 获取当前头节点的下一个节点
|
||||
newNode->prev = sentinelNode; // 新节点的上一个节点指向哨兵节点
|
||||
newNode->next = next; // 新节点的下一个节点指向原来的头节点
|
||||
size++; // 链表大小加1
|
||||
sentinelNode->next = newNode; // 哨兵节点的下一个节点指向新节点
|
||||
next->prev = newNode; // 原来的头节点的上一个节点指向新节点
|
||||
}
|
||||
|
||||
// 在链表尾部添加节点
|
||||
void addAtTail(int val) {
|
||||
DList *newNode = new DList(val); // 创建新节点
|
||||
DList *prev = sentinelNode->prev; // 获取当前尾节点的上一个节点
|
||||
newNode->next = sentinelNode; // 新节点的下一个节点指向哨兵节点
|
||||
newNode->prev = prev; // 新节点的上一个节点指向原来的尾节点
|
||||
size++; // 链表大小加1
|
||||
sentinelNode->prev = newNode; // 哨兵节点的上一个节点指向新节点
|
||||
prev->next = newNode; // 原来的尾节点的下一个节点指向新节点
|
||||
}
|
||||
|
||||
// 在链表中的第index个节点之前添加值为val的节点
|
||||
void addAtIndex(int index, int val) {
|
||||
if (index > size) { // 检查索引是否超出范围
|
||||
return; // 如果超出范围,直接返回
|
||||
}
|
||||
if (index <= 0) { // 如果索引为0或负数,在头部添加节点
|
||||
addAtHead(val);
|
||||
return;
|
||||
}
|
||||
int num;
|
||||
int mid = size >> 1; // 计算链表中部位置
|
||||
DList *curNode = sentinelNode; // 从哨兵节点开始
|
||||
if (index < mid) { // 如果索引小于中部位置,从前往后遍历
|
||||
for (int i = 0; i < index; i++) {
|
||||
curNode = curNode->next; // 移动到目标位置的前一个节点
|
||||
}
|
||||
DList *temp = curNode->next; // 获取目标位置的节点
|
||||
DList *newNode = new DList(val); // 创建新节点
|
||||
curNode->next = newNode; // 在目标位置前添加新节点
|
||||
temp->prev = newNode; // 目标位置的节点的前一个节点指向新节点
|
||||
newNode->next = temp; // 新节点的下一个节点指向目标位置的结点
|
||||
newNode->prev = curNode; // 新节点的上一个节点指向当前节点
|
||||
} else { // 如果索引大于等于中部位置,从后往前遍历
|
||||
for (int i = 0; i < size - index; i++) {
|
||||
curNode = curNode->prev; // 移动到目标位置的后一个节点
|
||||
}
|
||||
DList *temp = curNode->prev; // 获取目标位置的节点
|
||||
DList *newNode = new DList(val); // 创建新节点
|
||||
curNode->prev = newNode; // 在目标位置后添加新节点
|
||||
temp->next = newNode; // 目标位置的节点的下一个节点指向新节点
|
||||
newNode->prev = temp; // 新节点的上一个节点指向目标位置的节点
|
||||
newNode->next = curNode; // 新节点的下一个节点指向当前节点
|
||||
}
|
||||
size++; // 链表大小加1
|
||||
}
|
||||
|
||||
// 删除链表中的第index个节点
|
||||
void deleteAtIndex(int index) {
|
||||
if (index > (size - 1) || index < 0) { // 检查索引是否超出范围
|
||||
return; // 如果超出范围,直接返回
|
||||
}
|
||||
int num;
|
||||
int mid = size >> 1; // 计算链表中部位置
|
||||
DList *curNode = sentinelNode; // 从哨兵节点开始
|
||||
if (index < mid) { // 如果索引小于中部位置,从前往后遍历
|
||||
for (int i = 0; i < index; i++) {
|
||||
curNode = curNode->next; // 移动到目标位置的前一个节点
|
||||
}
|
||||
DList *next = curNode->next->next; // 获取目标位置的下一个节点
|
||||
curNode->next = next; // 删除目标位置的节点
|
||||
next->prev = curNode; // 目标位置的下一个节点的前一个节点指向当前节点
|
||||
} else { // 如果索引大于等于中部位置,从后往前遍历
|
||||
for (int i = 0; i < size - index - 1; i++) {
|
||||
curNode = curNode->prev; // 移动到目标位置的后一个节点
|
||||
}
|
||||
DList *prev = curNode->prev->prev; // 获取目标位置的下一个节点
|
||||
curNode->prev = prev; // 删除目标位置的节点
|
||||
prev->next = curNode; // 目标位置的下一个节点的下一个节点指向当前节点
|
||||
}
|
||||
size--; // 链表大小减1
|
||||
}
|
||||
|
||||
private:
|
||||
int size; // 链表的大小
|
||||
DList *sentinelNode; // 哨兵节点的指针
|
||||
};
|
||||
```
|
||||
|
||||
### C:
|
||||
|
||||
```C
|
||||
|
Reference in New Issue
Block a user