C++中的鏈表操作

在C++中,鏈表是一種常見的數據結構,它由一系列節點組成,每個節點包含數據部分和指向下一個節點的指針。C++標準庫(STL)中提供了std::liststd::forward_list兩種鏈表實現,分別對應雙向鏈表和單向鏈表。此外,也可以通過手動實現鏈表來加深對鏈表的理解。

1. C++標準庫中的鏈表

(1)std::list(雙向鏈表)

std::list是C++標準庫中的雙向鏈表實現,每個節點包含指向前一個節點和后一個節點的指針。它支持高效的插入和刪除操作,但隨機訪問效率較低。

  • 基本操作

    #include <iostream>
    #include <list>int main() {std::list<int> myList;// 插入元素myList.push_back(10); // 在鏈表尾部插入myList.push_front(20); // 在鏈表頭部插入myList.insert(myList.begin() + 1, 30); // 在指定位置插入// 遍歷鏈表for (int value : myList) {std::cout << value << " ";}std::cout << std::endl;// 刪除元素myList.pop_back(); // 刪除尾部元素myList.pop_front(); // 刪除頭部元素myList.erase(myList.begin() + 1); // 刪除指定位置的元素// 遍歷鏈表for (int value : myList) {std::cout << value << " ";}std::cout << std::endl;return 0;
    }
(2)std::forward_list(單向鏈表)

std::forward_list是C++11引入的單向鏈表實現,每個節點只包含指向下一個節點的指針。它比std::list更輕量,但只能單向遍歷。

  • 基本操作

    #include <iostream>
    #include <forward_list>int main() {std::forward_list<int> myList;// 插入元素myList.push_front(10); // 在鏈表頭部插入myList.push_front(20);myList.insert_after(myList.begin(), 30); // 在指定位置插入// 遍歷鏈表for (int value : myList) {std::cout << value << " ";}std::cout << std::endl;// 刪除元素myList.pop_front(); // 刪除頭部元素myList.erase_after(myList.begin()); // 刪除指定位置的元素// 遍歷鏈表for (int value : myList) {std::cout << value << " ";}std::cout << std::endl;return 0;
    }

2. 手動實現鏈表

手動實現鏈表可以幫助更好地理解鏈表的內部機制。以下是單向鏈表和雙向鏈表的基本實現。

(1)單向鏈表
#include <iostream>// 定義鏈表節點
struct Node {int data;Node* next;Node(int value) : data(value), next(nullptr) {}
};// 定義鏈表類
class LinkedList {
private:Node* head;public:LinkedList() : head(nullptr) {}// 插入元素到鏈表尾部void append(int value) {Node* newNode = new Node(value);if (head == nullptr) {head = newNode;} else {Node* current = head;while (current->next != nullptr) {current = current->next;}current->next = newNode;}}// 插入元素到鏈表頭部void prepend(int value) {Node* newNode = new Node(value);newNode->next = head;head = newNode;}// 刪除元素void remove(int value) {if (head == nullptr) return;if (head->data == value) {Node* temp = head;head = head->next;delete temp;return;}Node* current = head;while (current->next != nullptr && current->next->data != value) {current = current->next;}if (current->next != nullptr) {Node* temp = current->next;current->next = temp->next;delete temp;}}// 遍歷鏈表void print() const {Node* current = head;while (current != nullptr) {std::cout << current->data << " ";current = current->next;}std::cout << std::endl;}// 析構函數,釋放鏈表內存~LinkedList() {Node* current = head;while (current != nullptr) {Node* temp = current;current = current->next;delete temp;}}
};int main() {LinkedList list;list.append(10);list.append(20);list.prepend(5);list.print(); // 輸出:5 10 20list.remove(10);list.print(); // 輸出:5 20return 0;
}
(2)雙向鏈表
#include <iostream>// 定義鏈表節點
struct Node {int data;Node* next;Node* prev;Node(int value) : data(value), next(nullptr), prev(nullptr) {}
};// 定義鏈表類
class DoublyLinkedList {
private:Node* head;Node* tail;public:DoublyLinkedList() : head(nullptr), tail(nullptr) {}// 插入元素到鏈表尾部void append(int value) {Node* newNode = new Node(value);if (head == nullptr) {head = newNode;tail = newNode;} else {tail->next = newNode;newNode->prev = tail;tail = newNode;}}// 插入元素到鏈表頭部void prepend(int value) {Node* newNode = new Node(value);if (head == nullptr) {head = newNode;tail = newNode;} else {newNode->next = head;head->prev = newNode;head = newNode;}}// 刪除元素void remove(int value) {Node* current = head;while (current != nullptr && current->data != value) {current = current->next;}if (current == nullptr) return;if (current->prev != nullptr) {current->prev->next = current->next;} else {head = current->next;}if (current->next != nullptr) {current->next->prev = current->prev;} else {tail = current->prev;}delete current;}// 遍歷鏈表void print() const {Node* current = head;while (current != nullptr) {std::cout << current->data << " ";current = current->next;}std::cout << std::endl;}// 析構函數,釋放鏈表內存~DoublyLinkedList() {Node* current = head;while (current != nullptr) {Node* temp = current;current = current->next;delete temp;}}
};int main() {DoublyLinkedList list;list.append(10);list.append(20);list.prepend(5);list.print(); // 輸出:5 10 20list.remove(10);list.print(); // 輸出:5 20return 0;
}

總結

  • 標準庫鏈表std::liststd::forward_list提供了豐富的功能和高效的插入刪除操作,適合大多數應用場景。

  • 手動實現鏈表:通過手動實現鏈表,可以加深對鏈表內部機制的理解,例如節點的創建、插入、刪除和內存管理等。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76528.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76528.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76528.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

蛋白設計 ProteinMPNN

傳統方法的局限性是什么&#xff1f; 傳統蛋白質設計方法的局限性&#xff1a; 基于物理的傳統方法&#xff0c;例如羅塞塔&#xff0c;面臨計算難度&#xff0c;因為需要計算所有可能結構的能量&#xff0c;包括不需要的寡聚態和聚合態。 設計目標與顯式優化之間缺乏一致性通…

有哪些開源的視頻生成模型

1. 阿里巴巴通義萬相2.1&#xff08;WanX 2.1&#xff09; 技術架構&#xff1a;基于Diffusion Transformer&#xff08;DiT&#xff09;架構&#xff0c;結合自研的高效變分自編碼器&#xff08;VAE&#xff09;和Flow Matching訓練方案&#xff0c;支持時空上下文建模。參數…

【動態規劃】最長上升子序列模板

最長上升子序列 題目傳送門 一、題目描述 給定一個長度為 N 的數列&#xff0c;求數值嚴格單調遞增的子序列的長度最長是多少。 輸入格式 第一行包含整數 N。 第二行包含 N 個整數&#xff0c;表示完整序列。 輸出格式 輸出一個整數&#xff0c;表示最大長度。 數據范圍 …

LeetCode 891 -- 貢獻度思想

題目描述 子序列寬度之和 思路 ref 代碼 相似題 子數組范圍和 acwing

化工行業如何通過定制化工作流自動化實現25-30%成本優化?

作者&#xff1a;Mihir Jhaveri 編譯&#xff1a;李升偉 發布日期&#xff1a;2024年10月30日 在化工生產領域&#xff0c;數字化轉型正以顛覆性態勢重塑產業格局。通過集成定制化軟件、ERP系統、工業物聯網&#xff08;IIoT&#xff09;傳感網絡、機器人流程自動化&#xff0…

Compose組件轉換XML布局

文章目錄 學習JetPack Compose資源前言&#xff1a;預覽界面的實現Compose組件的布局管理一、Row和Colum組件&#xff08;LinearLayout&#xff09;LinearLayout&#xff08;垂直方向 → Column&#xff09;LinearLayout&#xff08;水平方向 → Row&#xff09; 二、相對布局 …

RAG測試數據集資源

一、通用問答基準數據集 HotpotQA 特點:包含11萬+多跳問答對最佳用途:測試復雜推理能力數據示例:{"question": "Were Scott Derrickson and Ed Wood of the same nationality?","answer": "Yes, both are American" }MS MARCO 特點…

快速掌握MCP——Spring AI MCP包教包會

最近幾個月AI的發展非常快&#xff0c;各種大模型、智能體、AI名詞和技術和框架層出不窮&#xff0c;作為一個業余小紅書博主的我最近總刷到MCP這個關鍵字&#xff0c;看著有點高級我也來學習一下。 1.SpringAI與functionCall簡單回顧 前幾個月我曾寫過兩篇關于SpringAI的基礎…

學習筆記--(6)

import numpy as np import matplotlib.pyplot as plt from scipy.special import erfc# 設置參數 rho 0.7798 z0 4.25 # 確保使用大寫 Z0&#xff0c;與定義一致def calculate_tau(z, z_prime, rho, s_values):return np.log(rho * z * z_prime * s_values / 2)# 定義 chi_…

【AI4CODE】5 Trae 錘一個基于百度Amis的Crud應用

【AI4CODE】目錄 【AI4CODE】1 Trae CN 錐安裝配置與遷移 【AI4CODE】2 Trae 錘一個 To-Do-List 【AI4CODE】3 Trae 錘一個貪吃蛇的小游戲 【AI4CODE】4 Trae 錘一個數據搬運工的小應用 1 百度 Amis 簡介 百度 Amis 是一個低代碼前端框架&#xff0c;由百度開源。它通過 J…

認識 Promise

認識 Promise 前言&#xff1a;為什么會出現 Promise&#xff1f; 最常見的一個場景就是 ajax 請求&#xff0c;通俗來說&#xff0c;由于網速的不同&#xff0c;可能你得到返回值的時間也是不同的&#xff0c;這個時候我們就需要等待&#xff0c;結果出來了之后才知道怎么樣…

純c++實現transformer 訓練+推理

項目地址 https://github.com/freelw/cpp-transformer C 實現的 Transformer 這是一個無需依賴特殊庫的 Transformer 的 C 實現&#xff0c;涵蓋了訓練與推理功能。 本項目使用C復刻了《Dive into Deep Learning》中關于 Transformer 的第 11 章11.7小節點內容。構建了一個英…

Go 語言規范學習(7)

文章目錄 Built-in functionsAppending to and copying slicesClearCloseManipulating complex numbersDeletion of map elementsLength and capacityMaking slices, maps and channelsMin and maxAllocationHandling panicsBootstrapping PackagesSource file organizationPac…

Python Cookbook-5.1 對字典排序

任務 你想對字典排序。這可能意味著需要先根據字典的鍵排序&#xff0c;然后再讓對應值也處于同樣的順序。 解決方案 最簡單的方法可以通過這樣的描述來概括:先將鍵排序&#xff0c;然后由此選出對應值: def sortedDictValues(adict):keys adict.keys()keys.sort()return …

Git Rebase 操作中丟失提交的恢復方法

背景介紹 在團隊協作中,使用 Git 進行版本控制是常見實踐。然而,有時在執行 git rebase 或者其他操作后,我們可能會發現自己的提交記錄"消失"了,這往往讓開發者感到恐慌。本文將介紹幾種在 rebase 后恢復丟失提交的方法。 問題描述 當我們執行以下操作時,可能…

C語言基礎要素(019):輸出ASCII碼表

計算機以二進制處理信息&#xff0c;但二進制對人類并不友好。比如說我們規定用二進制值 01000001 表示字母’A’&#xff0c;顯然通過鍵盤輸入或屏幕閱讀此數據而理解它為字母A&#xff0c;是比較困難的。為了有效的使用信息&#xff0c;先驅者們創建了一種稱為ASCII碼的交換代…

鴻蒙定位開發服務

引言 鴻蒙操作系統&#xff08;HarmonyOS&#xff09;作為面向萬物互聯時代的分布式操作系統&#xff0c;其定位服務&#xff08;Location Kit&#xff09;為開發者提供了多場景、高精度的位置能力支持。本文將從技術原理、開發流程到實戰案例&#xff0c;全面解析鴻蒙定位服務…

rknn_convert的使用方法

rknn_convert是RKNN-Toolkit2提供的一套常用模型轉換工具&#xff0c;通過封裝上述API接口&#xff0c;用戶只需編輯模型對應的yml配置文件&#xff0c;就可以通過指令轉換模型。以下是如何使用rknn_convert工具的示例命令以及支持的指令參數&#xff1a; python -m rknn.api.…

解決 axios get請求瞎轉義問題

在Vue.js項目中&#xff0c;axios 是一個常用的HTTP客戶端庫&#xff0c;用于發送HTTP請求。qs 是一個用于處理查詢字符串的庫&#xff0c;通常與 axios 結合使用&#xff0c;特別是在處理POST請求時&#xff0c;將對象序列化為URL編碼的字符串。 1. 安裝 axios 和 qs 首先&a…

【XTerminal】【樹莓派】Linux系統下的函數調用編程

目錄 一、XTerminal下的Linux系統調用編程 1.1理解進程和線程的概念并在Linux系統下完成相應操作 (1) 進程 (2)線程 (3) 進程 vs 線程 (4)Linux 下的實踐操作 1.2Linux的“虛擬內存管理”和stm32正式物理內存&#xff08;內存映射&#xff09;的區別 (1)Linux虛擬內存管…