mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-07 07:35:35 +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:
|
||||||
|
|
||||||
```C
|
```C
|
||||||
|
Reference in New Issue
Block a user