
文章目录QT_QList 与 QLinkedListQT_QList 与 QLinkedList对比QList创建与初始化添加元素访问元素删除元素查找与替换截取与合并大小与状态QLinkedList创建与初始化添加元素访问元素 有限制删除元素查找与 std::list 互转QList 与 QLinkedList的迭代器QList 的迭代器QLinkedList 的迭代器隐式共享写时复制总结QT_QList 与 QLinkedListQList在Qt 6中与QVector完全等价底层是连续内存动态数组元素紧挨着存放在一块连续的内存中。QLinkedList底层是双向链表每个节点独立分配在堆上通过前驱/后继指针串联。QT_QList 与 QLinkedList对比操作QListQLinkedList按索引访问list[i]O(1)不支持尾部追加append()O(1) 均摊O(1)头部插入prepend()O(n)O(1)中间插入已知位置O(n)需移动后续元素O(1)只改指针删除已知位置O(n)需移动后续元素O(1)只改指针查找按值O(n)O(n)遍历快内存连续缓存命中率高慢指针跳转缓存不友好内存占用小仅数据本身大每个节点额外2个指针QList创建与初始化#includeQListQListintlist1;// 空列表QListintlist2{10,20,30};// 初始化列表C11QListintlist3(5);// 5个元素默认值0QListQStringlist4(5,hello);// 5个元素全部为helloQListintlist5list2;// 拷贝构造隐式共享O(1)添加元素QListintlist;list.append(10);// 末尾添加 → [10]list.append(20);// 末尾添加 → [10, 20]list.prepend(5);// 头部添加 → [5, 10, 20]list.insert(1,8);// 在索引1处插入 → [5, 8, 10, 20]list3040;// 流式插入 → [5, 8, 10, 20, 30, 40]list.push_back(50);// 等同于 append → [5, 8, 10, 20, 30, 40, 50]list.push_front(1);// 等同于 prepend → [1, 5, 8, 10, 20, 30, 40, 50]访问元素QListintlist{10,20,30,40,50};list[0];// 10可读可写list[0]99;// 修改第一个元素list.at(1);// 20只读比 [] 更快不触发深拷贝list.first();// 99第一个元素可读可写list.last();// 50最后一个元素可读可写list.constFirst();// 99只读版本list.constLast();// 50只读版本list.value(10);// 索引越界时返回默认值0不崩溃list.value(10,-1);// 索引越界时返回-1list.data();// 返回指向第一个元素的指针可传给C函数删除元素QListintlist{10,20,30,40,50};list.removeAt(2);// 删除索引2 → [10, 20, 40, 50]list.removeFirst();// 删除第一个 → [20, 40, 50]list.removeLast();// 删除最后一个 → [20, 40]list.removeOne(20);// 删除第一个值为20的 → [40]list.removeAll(40);// 删除所有值为40的 → []list.clear();// 清空所有元素// take 系列删除并返回被删元素intval1list.takeAt(1);// 删除索引1并返回它intval2list.takeFirst();// 删除第一个并返回它intval3list.takeLast();// 删除最后一个并返回它// erase通过迭代器删除autoitlist.begin()1;list.erase(it);// 删除迭代器指向的元素list.erase(list.begin(),list.begin()2);// 删除一个范围查找与替换QListintlist{10,20,30,20,40};list.indexOf(20);// 1首次出现的索引list.lastIndexOf(20);// 3最后出现的索引list.contains(30);// truelist.count(20);// 2出现次数list.replace(2,99);// 将索引2替换为99 → [10, 20, 99, 20, 40]截取与合并QListintlist{10,20,30,40,50};QListintsublist.mid(1,3);// 从索引1取3个 → [20, 30, 40]QListintsub2list.mid(2);// 从索引2取到末尾 → [30, 40, 50]QListinta{1,2};QListintb{3,4};QListintcab;// 合并 → [1, 2, 3, 4]ab;// a 变为 [1, 2, 3, 4]大小与状态list.size();// 元素个数list.count();// 等同于 size()list.isEmpty();// 是否为空list.empty();// 等同于 isEmpty()STL兼容QLinkedList创建与初始化#includeQLinkedListQLinkedListintlist1;// 空链表QLinkedListintlist2{10,20,30};// 初始化列表C11QLinkedListintlist3list2;// 拷贝构造隐式共享O(1)添加元素QLinkedListintlist;list.append(10);// 尾部添加 → [10]list.append(20);// 尾部添加 → [10, 20]list.prepend(5);// 头部添加 → [5, 10, 20]O(1)比QList快list3040;// 流式插入 → [5, 10, 20, 30, 40]list.push_back(50);// 等同于 appendlist.push_front(1);// 等同于 prepend访问元素 有限制QLinkedListintlist{10,20,30,40,50};list[0];// 编译报错QLinkedList不支持索引访问list.at(1);// 编译报错list.indexOf(20);// 没有这个方法list.mid(1,3);// 没有这个方法// 只能这样访问list.first();// 10第一个元素list.last();// 50最后一个元素list.front();// 10STL兼容等同于firstlist.back();// 50STL兼容等同于lastlist.startsWith(10);// truelist.endsWith(50);// true删除元素QLinkedListintlist{10,20,30,40,50};list.removeFirst();// 删除第一个 → [20, 30, 40, 50]list.removeLast();// 删除最后一个 → [20, 30, 40]list.removeOne(30);// 删除第一个值为30的 → [20, 40]list.removeAll(20);// 删除所有值为20的 → [40]list.clear();// 清空// take 系列删除并返回intval1list.takeFirst();// 删除第一个并返回intval2list.takeLast();// 删除最后一个并返回// erase通过迭代器删除O(1)autoitlist.begin();it;list.erase(it);// 删除迭代器指向的元素O(1)查找QLinkedListintlist{10,20,30,20,40};list.contains(20);// true需要遍历O(n)list.count(20);// 2需要遍历O(n)与 std::list 互转// QLinkedList → std::listQLinkedListdoubleqlist{1.2,0.5,3.14};std::listdoublestdlistqlist.toStdList();// std::list → QLinkedListstd::listdoublestdlist2{1.1,2.2,3.3};QLinkedListdoubleqlist2QLinkedListdouble::fromStdList(stdlist2);QList 与 QLinkedList的迭代器QList 的迭代器QListintlist{10,20,30,40,50};// STL 风格推荐 // 只读迭代器for(autoitlist.constBegin();it!list.constEnd();it)qDebug()*it;// 读写迭代器for(autoitlist.begin();it!list.end();it){*it*it*2;// 可以修改元素}// C11 范围 for最简洁for(intval:list)qDebug()val;// Java 风格 // 只读QListIteratorintit(list);while(it.hasNext())qDebug()it.next();// 读写QMutableListIteratorintmit(list);while(mit.hasNext()){intvalmit.next();if(val30)mit.remove();// 删除当前元素}QLinkedList 的迭代器QLinkedListintlist{10,20,30,40,50};// STL 风格 // 只读迭代器for(autoitlist.constBegin();it!list.constEnd();it)qDebug()*it;// 读写迭代器for(autoitlist.begin();it!list.end();it)*it*it*2;// C11 范围 forfor(intval:list)qDebug()val;// 迭代器插入/删除QLinkedList 的核心优势 autoitlist.begin();it;// 指向第二个元素list.insert(it,15);// 在20前面插入15O(1)list.erase(it);// 删除20O(1)// Java 风格 QLinkedListIteratorintit2(list);while(it2.hasNext())qDebug()it2.next();QMutableLinkedListIteratorintmit(list);while(mit.hasNext()){intvalmit.next();if(val30)mit.remove();}隐式共享写时复制两者都支持隐式共享赋值和传参时不会立即复制数据只有在修改时才真正复制。QListintlist1{10,20,30};QListintlist2list1;// O(1)不复制数据共享同一内存list2[0]99;// 此时才触发深拷贝写时复制// list1: [10, 20, 30] ← 不受影响// list2: [99, 20, 30]总结QListQLinkedList使用频率95% 的场景5% 的场景默认选择是否适用场景通用几乎万能频繁头/中间插入删除 不需要索引访问Qt官方建议优先使用仅在性能测试证明更快时才用实践原则先用QList写代码如果性能测试发现瓶颈在插入/删除操作上再考虑换成QLinkedList。不要过早优化。end~