news 2026/9/4 8:25:42

C++综合实战:数据结构与算法实现及系列总结

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++综合实战:数据结构与算法实现及系列总结

本文是 C++ 系列教程的第 30 篇,也是系列终章。本篇实战数据结构与算法:手写动态数组与链表、排序与查找算法、递归与分治,最后回顾全部 30 篇学习路径,覆盖 9 个完整示例代码。

一、手写动态数组

1.1 为什么手写容器

理解容器内部机制是 C++ 进阶的必经之路。手写一个简化版 `vector,体会内存管理、扩容与拷贝语义:

// my_vector.h —— 简化版动态数组#pragmaonce#include<iostream>usingnamespacestd;template<typenameT>classMyVector{private:T*data;// 指向堆内存size_t sz;// 当前元素个数size_t cap;// 容量voidgrow(){// 扩容:翻倍cap=cap==0?4:cap*2;T*newData=newT[cap];for(size_t i=0;i<sz;++i)newData[i]=data[i];delete[]data;data=newData;}public:MyVector():data(nullptr),sz(0),cap(0){}~MyVector(){delete[]data;}voidpush_back(constT&value){if(sz==cap)grow();data[sz++]=value;}voidpop_back(){if(sz>0)sz--;}T&oper ator[](size_t i){returndata[i];}size_tsize()const{returnsz;}boolempty()const{returnsz==0;}};intmain(){MyVector<int>v;for(inti=1;i<=10;++i)v.push_back(i*i);cout<<"size = "<<v.size()<<endl;for(size_t i=0;i<v.size();++i)cout<<v[i]<<" ";// 1 4 9 16 25 36 49 64 81 100cout<<endl;return0;}

grow()在容量不足时翻倍扩容,均摊时间复杂度为 O(1)。注意实现析构函数释放堆内存避免泄漏。

1.2 迭代器与范围 for 支持

给容器加上简单的迭代器支持:

// 在 MyVector 中补充迭代器public:T*begin(){returndata;}T*end(){returndata+sz;}constT*begin()const{returndata;}constT*end()const{returndata+sz;}

有了begin()/end(),容器就能配合范围 for 循环

MyVector<int>nums;for(inti=0;i<5;++i)nums.push_back(i*3);for(intx:nums){// 范围 for:自动使用 begin/endcout<<x<<" ";// 0 3 6 9 12}cout<<endl;

二、链表实现

2.1 单链表

// linked_list.cpp —— 单链表#include<iostream>usingnamespacestd;structNode{intdata;Node*next;Node(intd):data(d),next(nullptr){}};classLinkedList{private:Node*head;public:LinkedList():head(nullptr){}~LinkedList(){Node*cur=head;while(cur){Node*tmp=cur;cur=cur->next;deletetmp;// 逐个释放,避免泄漏}}// 头插法voidinsertHead(intvalue){Node*n=newNode(value);n->next=head;head=n;}// 尾插法voidinsertTail(intvalue){Node*n=newNode(value);if(!head){head=n;return;}Node*cur=head;while(cur->next)cur=cur->next;cur->next=n;}boolremove(intvalue){if(!head)returnfalse;if(head->data==value){Node*tmp=head;head=head->next;deletetmp;returntrue;}Node*cur=head;while(cur->next&&cur->next->data!=value)cur=cur->next;if(!cur->next)returnfalse;Node*tmp=cur->next;cur->next=tm p=head;head=head->next;deletetmp;returntrue;}Node*cur=head;while(cur->next&&cur->next->data!=value)cur=cur->next;if(!cur->next)returnfalse;Node*tmp=cur->next;cur->next=tmp->next;deletetmp;returntrue;}voidshow()const{Node*cur=head;while(cur){cout<<cur->data<<" -> ";cur=cur->next;}cout<<"nullptr"<<endl;}};intmain(){LinkedList list;list.insertHead(3);list.insertHead(2);list.insertHead(1);// 1 -> 2 -> 3list.insertTail(4);// 1 -> 2 -> 3 -> 4list.show();list.remove(2);// 1 -> 3 -> 4list.show();return0;}

链表插入删除只需修改指针(O(1)),但随机访问需遍历(O(n));与数组恰好互补。

2.2 链表 vs 动态数组

特性动态数组链表
随机访问O(1)O(n)
头部插入O(n)(需移动)O(1)
尾部插入O(1)(均摊)O(1)
内存连续,缓存友好分散,缓
存不友好
额外开销少量(扩容时翻倍)每节点一个指针

三、排序算法

3.1 快速排序

// quick_sort.cpp —— 快速排序#include<iostream>#include<vector>usingnamespacestd;intpartition(vector<int>&arr,intlow,inthigh){intpivot=arr[high];// 取最后一个元素为基准inti=low-1;for(intj=low;j<high;++j){if(arr[j]<pivot){i++;swap(arr[i],arr[j]);}}swap(arr[i+1],arr[high]);returni+1;}voidquickSort(vector<int>&arr,intlow,inthigh){if(low<high){intpi=partition(arr,low,high);quickSort(arr,low,pi-1);// 递归左半quickSort(arr,pi+1,high);// 递归右半}}intmain(){vector<int>arr={10,7,8,9,1,5};quickSort(arr,0,(int)arr.size()-1);for(intx:arr)cout<<x<<" ";cout<<endl;// 1 5 7 8 9 10return0;}

快速排序平均 O(n log n),通过分治思想每次把基准放到最终位置,两边递归。

3.2 归并排序

// merge_sort.cpp —— 归并排序#include<iostream>#include<vector>usingnamespacestd;voidmerge(vector<int>&arr,intleft,intmid,intright){vector<int>tmp(right-left+1);inti=left,j=mid+1,k=0;while(i<=mid&&j<=right)tmp[k++]=(arr[i]<=arr[j])?arr[i++]:arr[j++];while(i<=mid)tmp[k++]=arr[i++];while(j<=right)tmp[k++]=arr[j++];for(intt=0;t<(int)tmp.size();++t)arr[left+t]=tmp[t];}voidmergeSort(vector<int>&arr,intleft,intright){if(left>=right)return;intmid=(left+right)/2;mergeSort(arr,left,mid);// 分mergeSort(arr,mid+1,right);merge(arr,left,mid,right);// 治:合并两个有序段}intmain(){vector<int>arr={38,27,43,3,9,82,10};mergeSort(arr,0,(int)arr.size()-1);for(intx:arr)cout<<x<<" ";cout<<endl;// 3 9 10 27 38 43 82return0;}

归并排序稳定、O(n log n),需要额外 O(n) 空间。快速排序空间 O(log n) 但不稳定

四、查找算法

4.1 二分查找

// binary_search.cpp —— 二分查找(要求数组有序)#include<iostream>#include<vector>usingnamespacestd;intbinarySearch(constvector<int>&arr,inttarget){intleft=0,right=(int)arr.size()-1;while(left<=right){intmid=left+(right-left)/2;// 防止溢出if(arr[mid]==target)returnmid;if(arr[mid]<target)left=mid+1;elseright=mid-1;}return-1;// 未找到}intmain(){vector<int>arr={1,3,5,7,9,11,13};cout<<binarySearch(arr,7)<<endl;// 3(下标)cout<<binarySearch(arr,8)<<endl;// -1(不存在)return0;}

二分查找每次排除一半区间,O(log n)。mid = left + (right - left) / 2避免(left+right)溢出。

五、实战:学生成绩管理系统(综合)

综合运用容器、排序、查找、lambda 与统计的完整案例:

// student_manager.cpp —— 学生成绩管理#include<iostream>#include<vector>#include<string>#include<algorithm>#include<numeric>usingnamespacestd;structStudent{string name;intscore;};voidshowAll(constvector<Student>&students){for(constauto&s:students)cout<<s.name<<" "<<s.score<<endl;}intmain(){vector<Student>students={{"张三",85},{"李四",92},{"王五",78},{"赵六",95}};// 1. 按分数降序排序(lambda 比较)sort(students.begin(),students.end(),[](constStudent&a,constStudent&b){returna.score>b.score;});cout<<"按分数降序:"<<endl;showAll(students);// 2. 计算平均分(accumulate 求和)doubleavg=accumulate(students.begin(),students.end(),0.0,[](doublesum,constStudent&s){returnsum+s.score;})/students.size();cout<<"平均分: "<<avg<<endl;// 3. 查找最高分autobest=max_element(students.begin(),students.end(),[](constStudent&a,constStudent&b){returna.score<b.score;});cout<<"最高分: "<<best->name<<" "<<best->score<<endl;// 4. 统计及格人数(count_if)intpassed=count_if(students.begin(),students.end(),[](constStudent&s){returns.score>=60;});cout<<"及格人数: "<<passed<<endl;return0;}

六、30 篇系列总结

6.1 学习路径回顾

本系列从零到实战覆盖 C++ 全链路:

阶段篇目核心内容
入门1-5语法基础、控制流、函数、数组/指针、类初探
进阶6-10类与对象、运算符重载、继承多态、内存管理、文件流
STL11-15容器、迭代器、算法库、函数对象/Lambda、适配器
模板16-19函数/类模板、特化与萃取、变参模板、完美转发
现代C++20-22C++11/14/17/20 新特性(智能指针、concepts、ranges)
并发23-25线程、互斥锁、条件变量、原子操作、线程池
工程化26-27CMake 构建、编译链接、GDB 调试、性能优化
实战28-30图书管理系统、HTTP 客户端、数据结构与算法

6.2 学习建议

  1. 动手写代码:每篇示例都亲手编译运行,改参数观察行为变化。
  2. 逐步进阶:按阶段顺序学习,模板与并发依赖前面基础。
  3. 结合工程:用 CMake 组织项目,用 GDB/ASan 排查问题。
  4. 阅读源码:理解vector/string等标准库内部实现。
  5. 持续练习:LeetCode 算法题、开源项目阅读,把知识用起来。

总结

作为系列终章,本篇实战了动态数组(手写 vector 与扩容)、链表(插入/删除与内存管理)、快速排序与归并排序(分治思想)、二分查找,并用学生成绩管理系统综合运用 STL 算法,最后回顾了 30 篇完整学习路径。从Hello World到网络编程、从模板元编程到并发线程池,你已经系统掌握了 C++ 的核心知识体系。持续编码、持续学习,C++ 的世界还很大,加油!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 8:25:13

2026年7月桂林市新房价格深度分析报告

一、报告背景与数据说明本报告基于2026年7月桂林市新房市场实际成交案例&#xff0c;结合各城区典型楼盘的真实成交数据&#xff0c;对当前桂林新房价格水平、区域分化特征及未来走势进行深度分析。数据来源涵盖桂林市住房和城乡建设局备案信息、主要房产交易平台公开成交记录及…

作者头像 李华
网站建设 2026/9/4 8:24:29

STM32F103ZET6智能小车红外循迹与超声波避障工程实践

简介&#xff1a;本资源是一套基于STM32F103ZET6主控的智能小车红外循迹与避障功能完整实现方案&#xff0c;面向嵌入式初学者、课程设计学生及电子竞赛备赛者&#xff0c;解决电机驱动、传感器数据采集、路径识别与实时运动控制等典型实践问题。压缩包共175个文件&#xff0c;…

作者头像 李华
网站建设 2026/9/4 8:24:14

ST7565液晶屏画线与双缓冲刷新实战指南

简介&#xff1a;本资源是一份面向嵌入式开发初学者与单片机工程师的ST7565液晶显示控制器画线功能实践代码&#xff0c;聚焦图形驱动核心能力训练&#xff0c;解决单色点阵屏上高效绘制任意直线的实际问题。压缩包为RAR格式&#xff0c;仅含1个C语言源文件&#xff08;st7565 …

作者头像 李华
网站建设 2026/9/4 8:23:52

Matlab机器视觉实战:从相机标定到物体尺寸精确测量

简介&#xff1a;本资源是一套面向机器视觉与图像处理领域工程技术人员的MATLAB实战方案&#xff0c;聚焦图像中物体实际尺寸的高精度检测问题&#xff0c;适用于工业自动化质检、精密制造测量及医疗影像分析等对尺度量化要求严格的场景。压缩包共7个文件&#xff08;5张JPEG测…

作者头像 李华
网站建设 2026/9/4 8:23:37

基于Baostock构建A股本地金融数据库:Python自动化下载与存储实战

简介&#xff1a;这是一套面向金融数据分析初学者与量化研究者的自动化数据获取工具&#xff0c;专为解决A股及主流指数历史K线数据手动采集效率低、覆盖不全、存储分散等实际问题而设计。工具基于稳定开源的Baostock金融数据接口&#xff0c;支持一键下载上证指数、深证成指、…

作者头像 李华
网站建设 2026/9/4 8:22:17

STM32F103实现SMTP邮件发送:嵌入式网络通信与协议解析实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华