数组 链表

数组:

结构在通过索引进行查询数据是效率比较高,而对于数组插入和删除操作则效率比较低,在第一个位置进行插入数据时,其它数据就需要依次后移,而删除一个数据,则该数据后的数据全部前移。

链表:

为了保证数据插入和删除不会影响其它数据的移动,保证线性开销,所以引出了链表。每个值都不会连续进行存储。链表是由一系列节点组成,每一个节点都有一个链点,就是next链。而next链则会执行下一个node引用,所以我们在插入和删除数据的时候,需要该链表next链的指向地址即可,每个节点不需要内存进行连续存储,这样会减少删除和插入的线性开销。

 

从逻辑结构上看:

1:数组必须事先定义固定的长度,不能实行动态数据的增减。当数据增加时,可能超出原先定义的元素个数,出现溢出现象。当数据减少时,造成内存浪费。数组中增减数据时需要移动其他数据。

2:链表动态的进行了存储分配,可以适应数据动态的增减,且方便的插入和删除数据。

 

从内存来看:

1(静态)数组从栈中分配空间,对于程序员来说方便快速,但自由度小。

2链表从堆中分配空间,自由度大,但申请管理比较麻烦

 

。。。该博文为摘抄  关于动态数组  及  单双向链表  没写  有机会补上

### C++ 中实现数组链表的方法 在C++中,数组链表是两种基础的数据结构,它们各自有不同的实现方式和应用场景。以下是详细的实现方法及其优缺点。 #### 数组的实现 数组是一种线性数据结构,存储在连续的内存空间中。C++中的数组可以通过静态数组或动态数组来实现。 ##### 静态数组 静态数组是在编译时确定大小的数组。例如: ```cpp int arr[10]; // 声明一个大小为10的整型数组 ``` 静态数组的优点是访问速度快,因为索引可以直接映射到内存地址。然而,它的缺点是大小固定,无法在运行时动态调整。 ##### 动态数组 动态数组通过`new`关键字在堆上分配内存,可以在运行时根据需要调整大小。例如: ```cpp int* arr = new int[10]; // 动态分配一个大小为10的整型数组 delete[] arr; // 释放内存 ``` 动态数组的优点是可以灵活地调整大小,但需要手动管理内存,增加了复杂性和潜在的内存泄漏风险。 #### 链表的实现 链表是一种非连续的数据结构,由节点组成,每个节点包含数据和指向下一个节点的指针。链表可以分为单向链表和双向链表。 ##### 单向链表 单向链表的每个节点只包含一个指向下一个节点的指针。以下是单向链表的基本实现: ```cpp struct Node { int data; Node* next; }; class LinkedList { private: Node* head; public: LinkedList() : head(nullptr) {} void insert(int value) { Node* newNode = new Node(); newNode->data = value; newNode->next = head; head = newNode; } void printList() { Node* current = head; while (current != nullptr) { std::cout << current->data << " "; current = current->next; } std::cout << std::endl; } }; ``` ##### 双向链表 双向链表的每个节点包含两个指针,分别指向前后节点。以下是双向链表的基本实现: ```cpp struct Node { int data; Node* prev; Node* next; }; class DoublyLinkedList { private: Node* head; Node* tail; public: DoublyLinkedList() : head(nullptr), tail(nullptr) {} void insertAtHead(int value) { Node* newNode = new Node(); newNode->data = value; newNode->prev = nullptr; newNode->next = head; if (head != nullptr) head->prev = newNode; else tail = newNode; head = newNode; } void printList() { Node* current = head; while (current != nullptr) { std::cout << current->data << " "; current = current->next; } std::cout << std::endl; } }; ``` #### 数组链表的比较 - **时间复杂度**:数组的随机访问时间为O(1),而链表的随机访问时间为O(n)。插入和删除操作在数组中需要移动元素,时间复杂度为O(n),而在链表中只需要修改指针,时间复杂度为O(1)。 - **空间效率**:数组的空间利用率较高,但需要预先分配足够的空间;链表的空间利用率较低,因为每个节点需要额外的指针空间[^3]。 #### 数组模拟链表 在某些情况下,使用数组模拟链表可以提高性能。这种方法结合了数组的随机访问优势和链表的动态调整特性。例如,使用数组存储节点,并通过索引模拟指针: ```cpp #include <iostream> using namespace std; const int N = 100010; int le[N], re[N], e[N], idx; void init() { le[0] = 0; re[0] = 1; idx = 2; } void insert(int pos, int value) { e[idx] = value; re[idx] = re[pos]; le[idx] = pos; le[re[pos]] = idx; re[pos] = idx; idx++; } ``` #### 优点与缺点 - **数组的优点**:访问速度快,适合频繁的随机访问。 - **数组的缺点**:插入和删除操作效率低,且大小固定。 - **链表的优点**:插入和删除操作高效,适合动态数据。 - **链表的缺点**:随机访问效率低,需要额外的内存空间[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值