从C语言到C++_17(list的模拟实现)list不是原生指针的迭代器

简介: 从C语言到C++_17(list的模拟实现)list不是原生指针的迭代器

在C++中,list是一个双向链表的容器,它提供了方便的插入、删除和访问元素的方法。其中,list迭代器是一个封装了指向链表节点的指针的对象,并提供了方便的操作链表的方法,与原生指针不同。

为了模拟list的实现,我们需要自己实现一个双向链表,并将其封装在一个类中,提供类似list的接口。

首先,我们定义链表节点的结构体:

template
struct Node {
T data;
Node prev;
Node
next;
Node(const T& d) : data(d), prev(nullptr), next(nullptr) {}
};

该结构体表示链表的一个节点,包含元素的值、前后两个指针,我们为它定义了一个构造函数,使用给定的元素值初始化节点。

然后,我们定义链表类:

template
class List {
public:
List();
~List();
void push_front(const T& val);
void push_back(const T& val);
void pop_front();
void pop_back();
T& front();
T& back();
bool empty() const;
size_t size() const;
private:
Node head;
Node
tail;
size_t list_size;
};

该类中包含了插入、删除、访问元素的方法,类似于list的接口。其中,head和tail分别指向链表的头、尾节点,list_size表示链表的大小。

下面是该类方法的实现:

template
List::List() : head(nullptr), tail(nullptr), list_size(0) {}

template
List::~List() {
while (head != nullptr) {
Node* tmp = head->next;
delete head;
head = tmp;
}
}

template
void List::push_front(const T& val) {
Node* new_node = new Node(val);
if (head == nullptr) {
head = tail = new_node;
} else {
new_node->next = head;
head->prev = new_node;
head = new_node;
}
++list_size;
}

template
void List::push_back(const T& val) {
Node* new_node = new Node(val);
if (head == nullptr) {
head = tail = new_node;
} else {
new_node->prev = tail;
tail->next = new_node;
tail = new_node;
}
++list_size;
}

template
void List::pop_front() {
if (head == nullptr) return;
if (head == tail) {
delete head;
head = tail = nullptr;
} else {
Node* tmp = head;
head = head->next;
head->prev = nullptr;
delete tmp;
}
--list_size;
}

template
void List::pop_back() {
if (head == nullptr) return;
if (head == tail) {
delete head;
head = tail = nullptr;
} else {
Node* tmp = tail;
tail = tail->prev;
tail->next = nullptr;
delete tmp;
}
--list_size;
}

template
T& List::front() {
return head->data;
}

template
T& List::back() {
return tail->data;
}

template
bool List::empty() const {
return head == nullptr;
}

template
size_t List::size() const {
return list_size;
}

注意到上述方法中,我们使用了封装了链表节点指针的Node*类型而不是原生指针,这样可以避免使用指针访问链表节点时的内存问题,提供了更安全的访问方式。

最后,使用类List就可以像list一样操作双向链表了:

List lst;
lst.push_back(1);
lst.push_back(2);
lst.push_back(3);
lst.pop_front();
lst.pop_back();
for (auto& x : lst) {
std::cout << x << " ";
}

如上述代码所示,我们可以通过调用push_back()和push_front()方法插入元素,通过pop_front()和pop_back()方法删除元素,通过front()和back()方法访问头尾元素,以及通过empty()和size()方法查看链表是否为空和大小等信息。

相关文章
|
9月前
|
安全 C语言 C++
比较C++的内存分配与管理方式new/delete与C语言中的malloc/realloc/calloc/free。
在实用性方面,C++的内存管理方式提供了面向对象的特性,它是处理构造和析构、需要类型安全和异常处理的首选方案。而C语言的内存管理函数适用于简单的内存分配,例如分配原始内存块或复杂性较低的数据结构,没有构造和析构的要求。当从C迁移到C++,或在C++中使用C代码时,了解两种内存管理方式的差异非常重要。
307 26
|
算法 C++ 容器
模拟实现c++中的list模版
模拟实现c++中的list模版
|
编译器 C语言 C++
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
335 2
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
470 7
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
1688 13
|
存储 编译器 C++
C++ initializer_list&&类型推导
在 C++ 中,`initializer_list` 提供了一种方便的方式来初始化容器和传递参数,而右值引用则是实现高效资源管理和移动语义的关键特性。尽管在实际应用中 `initializer_list&&` 并不常见,但理解其类型推导和使用方式有助于深入掌握现代 C++ 的高级特性。
231 4
|
存储 算法 C++
【C++打怪之路Lv10】-- list
【C++打怪之路Lv10】-- list
221 1
|
算法 编译器 C语言
【C语言】C++ 和 C 的优缺点是什么?
C 和 C++ 是两种强大的编程语言,各有其优缺点。C 语言以其高效性、底层控制和简洁性广泛应用于系统编程和嵌入式系统。C++ 在 C 语言的基础上引入了面向对象编程、模板编程和丰富的标准库,使其适合开发大型、复杂的软件系统。 在选择使用 C 还是 C++ 时,开发者需要根据项目的需求、语言的特性以及团队的技术栈来做出决策。无论是 C 语言还是 C++,了解其优缺点和适用场景能够帮助开发者在实际开发中做出更明智的选择,从而更好地应对挑战,实现项目目标。
605 0
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
244 0
|
存储 缓存 C++
C++番外篇——list与vector的比较
C++番外篇——list与vector的比较
327 0