源代碼:
#include <iostream>
#include <list>using namespace std;int main(){list<int> numbers={10,20,30};numbers.push_front(5);numbers.push_back(40);auto it =numbers.begin();advance(it,2);numbers.insert(it,15);cout<<"該列表的數為:";for(int num:numbers){cout<<num<<"\t";}numbers.remove(15);numbers.push_front(99);numbers.sort();cout<<endl;cout<<"該列表的數為:";for(int num:numbers){cout<<num<<"\t";}
}
運行結果:
該列表的數為:5 10 15 20 30 40
該列表的數為:5 10 20 30 40 99
請按任意鍵繼續. . .
代碼詳解與相關知識:
C++?std::list
?代碼解析及與C語言的對比
原始代碼解析
#include <iostream>
#include <list>using namespace std;int main(){// 初始化一個包含3個元素的listlist<int> numbers = {10, 20, 30};// 在頭部插入元素5numbers.push_front(5);// 在尾部插入元素40numbers.push_back(40);// 獲取迭代器并前進2個位置auto it = numbers.begin();advance(it, 2);// 在指定位置插入15numbers.insert(it, 15);// 輸出當前列表cout << "該列表的數為:";for(int num : numbers){cout << num << "\t";}// 刪除所有值為15的元素numbers.remove(15);// 在頭部插入99numbers.push_front(99);// 排序列表numbers.sort();// 輸出最終列表cout << endl;cout << "該列表的數為:";for(int num : numbers){cout << num << "\t";}
}
代碼執行流程
初始化列表:
[10, 20, 30]
頭部插入5:
[5, 10, 20, 30]
尾部插入40:
[5, 10, 20, 30, 40]
在位置2插入15:
[5, 10, 15, 20, 30, 40]
刪除15:
[5, 10, 20, 30, 40]
頭部插入99:
[99, 5, 10, 20, 30, 40]
排序后:
[5, 10, 20, 30, 40, 99]
C語言實現對比
C語言鏈表實現(等效功能)
#include <stdio.h>
#include <stdlib.h>typedef struct Node {int data;struct Node* prev;struct Node* next;
} Node;Node* createNode(int value) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = value;newNode->prev = NULL;newNode->next = NULL;return newNode;
}void insertFront(Node** head, int value) {Node* newNode = createNode(value);if (*head == NULL) {*head = newNode;return;}newNode->next = *head;(*head)->prev = newNode;*head = newNode;
}void insertBack(Node** head, int value) {Node* newNode = createNode(value);if (*head == NULL) {*head = newNode;return;}Node* temp = *head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;newNode->prev = temp;
}void insertAt(Node** head, int position, int value) {if (position == 0) {insertFront(head, value);return;}Node* newNode = createNode(value);Node* temp = *head;for (int i = 0; temp != NULL && i < position - 1; i++) {temp = temp->next;}if (temp == NULL) {free(newNode);return;}newNode->next = temp->next;if (temp->next != NULL) {temp->next->prev = newNode;}temp->next = newNode;newNode->prev = temp;
}void deleteValue(Node** head, int value) {Node* current = *head;while (current != NULL) {if (current->data == value) {if (current->prev != NULL) {current->prev->next = current->next;} else {*head = current->next;}if (current->next != NULL) {current->next->prev = current->prev;}Node* toDelete = current;current = current->next;free(toDelete);} else {current = current->next;}}
}void printList(Node* head) {Node* temp = head;while (temp != NULL) {printf("%d\t", temp->data);temp = temp->next;}printf("\n");
}// 簡化的排序實現(實際應該用更高效的排序)
void sortList(Node** head) {if (*head == NULL || (*head)->next == NULL) return;int swapped;Node* ptr1;Node* lptr = NULL;do {swapped = 0;ptr1 = *head;while (ptr1->next != lptr) {if (ptr1->data > ptr1->next->data) {int temp = ptr1->data;ptr1->data = ptr1->next->data;ptr1->next->data = temp;swapped = 1;}ptr1 = ptr1->next;}lptr = ptr1;} while (swapped);
}int main() {Node* head = NULL;// 初始化三個節點insertBack(&head, 10);insertBack(&head, 20);insertBack(&head, 30);// 頭部插入5insertFront(&head, 5);// 尾部插入40insertBack(&head, 40);// 在位置2插入15insertAt(&head, 2, 15);printf("該列表的數為:");printList(head);// 刪除值為15的節點deleteValue(&head, 15);// 頭部插入99insertFront(&head, 99);// 排序sortList(&head);printf("該列表的數為:");printList(head);// 釋放內存(實際應用中需要完整實現)return 0;
}
C++與C實現的關鍵區別
特性 | C++?std::list | C語言實現 |
---|---|---|
內存管理 | 自動管理(RAII) | 需手動malloc/free |
類型安全 | 模板實現,類型安全 | void*可能造成類型不安全 |
代碼復雜度 | 簡潔,高級抽象 | 冗長,需處理底層細節 |
功能完整性 | 提供完整成員函數(sort, merge等) | 需自行實現所有功能 |
異常安全 | 強異常安全保證 | 無異常處理機制 |
迭代器 | 提供標準迭代器 | 需手動用指針遍歷 |
性能優化 | 經過高度優化 | 實現質量取決于程序員 |
可維護性 | 接口穩定,文檔完善 | 維護成本高 |
線程安全 | 不同實例可并發訪問 | 完全無線程安全保證 |
擴展性 | 可輕松與其他STL組件配合 | 需額外工作與其他模塊集成 |
關鍵差異詳解
1. 內存管理
C++:利用構造函數/析構函數自動管理內存
{list<int> myList; // 自動初始化// ... 使用list ... } // 自動釋放所有內存
C:需手動分配和釋放
Node* head = NULL; // 初始化 // ... 使用鏈表 ... // 必須手動釋放所有節點 while (head != NULL) {Node* temp = head;head = head->next;free(temp); }
2. 迭代器 vs 指針
C++迭代器:
for (auto it = myList.begin(); it != myList.end(); ++it) {cout << *it << " "; }
C指針遍歷:
Node* current = head; while (current != NULL) {printf("%d ", current->data);current = current->next; }
3. 高級操作
C++內置算法:
myList.sort(); // 內置排序 myList.unique(); // 去重 myList.merge(otherList); // 合并
C需手動實現:
sortList(&head); // 自己實現的排序 removeDuplicates(&head); // 自己實現的去重 mergeLists(&head1, &head2); // 自己實現的合并
4. 類型安全
C++模板:
list<string> stringList; // 只能存儲字符串 stringList.push_back(10); // 編譯錯誤
C無類型檢查:
typedef struct Node {void* data; // 無類型安全 } Node;Node* node = (Node*)malloc(sizeof(Node)); node->data = (void*)10; // 可能造成問題
為什么選擇C++ list?
開發效率:減少樣板代碼,專注業務邏輯
安全性:自動內存管理避免內存泄漏
可維護性:標準接口更易于理解和維護
性能:標準庫實現通常經過充分優化
可擴展性:與其他STL組件無縫協作
何時需要用C實現?
嵌入式系統等受限環境(無STL支持)
需要完全控制內存布局和分配策略
與現有C代碼庫集成
特殊性能需求(如自定義內存池)
現代C++改進(C++11/14/17)
初始化列表:
list<int> nums = {1, 2, 3}; // C++11
自動類型推導:
auto it = nums.begin(); // 不需要寫list<int>::iterator
emplace操作:
nums.emplace_back(10); // 避免臨時對象構造
范圍for循環:
for (int num : nums) { ... } // 簡潔遍歷
結構化綁定(C++17):
for (auto& [index, value] : enumerate(nums)) { ... }
理解這些差異有助于根據項目需求選擇合適的實現方式。對于大多數現代C++項目,std::list
是更優的選擇,而在特定場景下可能需要考慮C實現。