C++和Python要点对比
本人以C++作为工作项目应用主语言 ,但是也会用到python,而且经常使用python作为力扣算法题的刷题主语言,经常发现容易混淆的函数、语法、和数据结构,于是想做个整理,持续更新。
提示:以下是本篇文章正文内容,下面案例可供参考
C++中的链表是一种线性数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。链表可以分为单向链表和双向链表。
单向链表:每个节点只有一个指向下一个节点的指针。
双向链表:每个节点有两个指针,一个指向前一个节点,另一个指向后一个节点。
下面是一个简单的单向链表实现及其示例:
#include
// 定义链表节点结构体
struct ListNode {
int val; // 数据域
ListNode *next; // 指针域,指向下一个节点
ListNode(int x) : val(x), next(NULL) {
} // 构造函数
};
// 创建链表
ListNode* createList(int arr[], int n) {
if (n == 0) return NULL;
ListNode *head = new ListNode(arr[0]);
ListNode *cur = head;
for (int i = 1; i < n; ++i) {
cur->next = new ListNode(arr[i]);
cur = cur->next;
}
return head;
}
// 打印链表
void printList(ListNode *head) {
ListNode *cur = head;
while (cur != NULL) {
std::cout << cur->val << " -> ";
cur = cur->next;
}
std::cout << "NULL" << std::endl;
}
int main() {
int arr[] = {
1, 2, 3, 4, 5};
ListNode *head = createList(arr, 5);
printList(head);
return 0;
}
也可以使用STL
C++的标准模板库(STL)中,std::list是一个双向链表容器,它允许在任何位置快速地插入和删除元素。std::list是模板类,可以存储任何类型的对象,包括基本数据类型、类对象和其它STL容器对象。
C++ STL中的std::list的特点:
双向链表:每个元素都是一个节点,包含数据和两个指向前一个和后一个节点的指针。
动态内存分配:std::list自动处理节点的内存分配和释放。
插入和删除操作效率高:由于std::list是链表结构,所以在任意位置插入和删除节点的操作都具有较高的效率,不需要移动其他元素。
不支持随机访问:与数组和std::vector不同,std::list不支持随机访问迭代器,因为它是链表结构,访问一个元素需要从头节点或尾节点遍历。
支持双向迭代器:std::list提供双向迭代器,可以从头到尾或从尾到头遍历链表。
大小可变:std::list的大小可以随时改变,可以根据需要动态增长和缩小。
std::list的简单使用示例:
#include
#include
int main() {
// 创建一个空的std::list
std::list<int> myList;
// 向list中添加元素
myList.push_back(1); // 在尾部添加元素
myList.push_front(2); // 在头部添加元素
// 插入元素到指定位置
auto it = myList.begin();
++it; // 移动到第二个元素
myList.insert(it, 3); // 在第二个元素后面插入新元素
// 删除元素
myList.remove(1); // 删除值为1的元素
// 遍历并打印元素
for (const auto& item : myList) {
std::cout << item << " ";
}
std::cout << std::endl;
// 输出链表大小
std::cout << "Size of list: " << myList.size() << std::endl;
return 0;
}
Python中没有内置的链表数据类型,但可以通过类来实现链表。
链表是一种数据结构,它通过指针将一系列节点连接起来,每个节点包含数据和指向下一个节点的指针。与数组不同,链表中的元素在内存中不是连续存储的,它们可以分散存储在内存的各个位置。链表有两种类型:单向链表和双向链表。单向链表的节点只有一个指向下一个节点的指针,而双向链表的节点既有指向下一个节点的指针,也有指向前一个节点的指针。
在Python中,虽然没有像C++ STL中的std::list那样的内置链表类型,但我们可以使用类(class)来自定义链表,并实现链表的各种操作。以下是实现链表的基本步骤:
定义节点:首先需要定义链表的节点类,每个节点包含数据部分和指向下一个节点的指针(或引用)。
定义链表:然后定义链表类,它通常包含对链表进行操作的方法,如添加节点、删除节点、遍历链表等。
操作链表:通过链表类提供的方法,可以对链表进行各种操作,如在链表头部或尾部添加新节点,或者在链表中搜索特定值的节点并删除它。
需要注意的是,由于Python的内存管理是自动的,使用链表时不需要担心内存分配和释放的问题,这一点与C++等语言有所不同。此外,Python的列表(list)实际上是一种动态数组,它在内部实现上与链表不同,但在功能上可以满足大多数链表的使用场景。如果需要在Python中实现链表,通常是因为学习数据结构的需要或者是因为链表在某些特定应用场景下的性能优势。
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def add_node(self, data):
new_node = Node(data)
if self.head is None:
self.head = new_node
else:
current = self.head
while current.next is not None:
current = current.next
current.next = new_node
def delete_node(self, data):
if self.head is None:
return
if self.head.data == data:
self.head = self.head.next
return
current = self.head
while current.next is not None and current.next.data != data:
current = current.next
if current.next is not None:
current.next = current.next.next
def traverse(self):
current = self.head
while current is not None:
print(current.data)
current = current.next
# 创建链表对象
my_list = LinkedList()
# 添加节点
my_list.add_node(1)
my_list.add_node(2)
my_list.add_node(3)
my_list.add_node(4)
my_list.add_node(5)
# 遍历链表
my_list.traverse() # 输出:1 2 3 4 5
# 删除节点
my_list.delete_node(3)
my_list.delete_node(1)
my_list.delete_node(5)
# 再次遍历链表
my_list.traverse() # 输出:2 4
C++中的vector是一种动态数组,它可以根据需要自动调整大小。vector是C++标准库中的一部分,位于头文件中。
vector的相关知识点:
动态数组:vector是一个动态数组,可以在运行时动态地增加或减少元素。
随机访问:vector支持随机访问,可以通过下标直接访问任意元素。
自动管理内存:vector会自动管理内存,当需要更多空间时,会自动分配新的内存,并将原有元素复制到新的位置。
支持迭代器:vector支持迭代器,可以使用迭代器遍历元素。
支持STL算法:vector支持STL算法,可以直接使用各种算法对vector进行操作。
vector的实现原理:
vector的内部实现基于动态数组,它维护了一个指向数组首元素的指针和一个表示数组大小的变量。当需要添加新元素时,如果数组已满,则会重新分配一个更大的数组,并将原有元素复制到新数组中。当删除元素时,如果数组过大,则会释放多余的空间。
std::vector<int> myVector;
myVector.push_back(1);
std::cout << "第一个元素:" << myVector[0] << std::endl;
// 在第二个位置插入一个元素
myVector.insert(myVector.begin() + 1, 4);
//使用范围for循环遍历vector
for (int num : myVector) {
std::cout << num << " ";
}
std::cout << std::endl;
// 删除最后一个元素
myVector.pop_back();
// 删除指定范围内的元素
myVector.erase(myVector.begin() + 1, myVector.begin() + 3);
// 将vector大小调整为5个元素
myVector.resize(5);
// 将vector大小调整为3个元素,多余的元素将被丢弃
myVector.resize(3);
// 预分配至少能容纳10个元素的内存空间
myVector.reserve(10);
以下是vector的所有成员函数及其示例:
构造函数相关:
vector():创建一个空的vector。
vector(n):创建一个包含n个元素的vector,每个元素默认初始化为0。
vector(n, val):创建一个包含n个元素的vector,每个元素都初始化为val。
vector(begin, end):创建一个包含指定范围内元素的vector。
vector(initList):使用初始化列表创建vector。
vector(otherVector):从另一个vector创建一个新的vector。
元素访问:
at(index):访问指定位置的元素,如果索引无效,会抛出out_of_range异常。
operator:访问指定位置的元素,不进行边界检查。
元素操作:
push_back(val):在vector的尾部添加一个新元素。
pop_back():删除vector的最后一个元素。
insert(iterator, element):在指定位置插入一个元素。
erase(iterator):删除指定位置的元素。
erase(first, last):删除指定范围内的元素。
clear():删除所有元素,但不释放内存。
大小和容量:
size():返回vector中元素的个数。
capacity():返回vector在不重新分配内存的情况下最多可以容纳的元素个数。
resize(newSize):调整vector的大小。
reserve(newCapacity):预分配内存,提高添加元素时的效率。
迭代器相关:
begin():返回指向第一个元素的迭代器。
end():返回指向最后一个元素之后的迭代器。
rbegin():返回指向最后一个元素的逆向迭代器。
rend():返回指向第一个元素之前的逆向迭代器。
其他函数:
empty():检查vector是否为空。
data():返回指向内部存储的第一个元素的指针。
在C++中,std::array
是C++11标准引入的一个STL容器,它提供了与原生数组类似的功能和性能。以下是std::array
的一些主要特点:
std::array
的大小在编译时必须是确定的,这意味着一旦创建,其大小不能更改。