Marching Cubes算法再回顾

1,确定包含等值面的体元

首先介绍一下 体元的概念,体元是三维图像中由相邻的八个体素点组成的正方体方格,英语也叫 Cube,体元中角点函数值分为两种情况,一种是大于等于给定等值面的值 C0 ,则将角点设为 1 称该角点在等值面内部,否则设为0,在等值面之外,

一般来说,会出现一个角点在内,一个角点在外,则角点之间的连线(也就是体元的边)必然与等值面相交,根据这个原理就能判断等值面与哪些体元相交。

——————————————————————————————————————

三维空间中,平行且相邻的两个二维图像(每个图像中的正方形四个像素顶点组成一个基本的像素图像单元)组成一个基本的三维图像单元。,下图中由6个这样的基本三维图像单元:

vtkImageData结构由尺寸、间距和原点来定义。尺寸标注是沿着每个主轴的体素或像素的数量。原点是数据的第一个切片的左下角的世界坐标位置。间距是沿三个主要轴的像素之间的距离。

原点是数据集左下角的世界坐标位置。

尺寸是沿着三个主要轴的体素或像素的数量。

间距是体素的高度、长度和宽度,或相邻像素之间的距离,这取决于是将数据视为相同的方框还是连续函数中的样本点。
——————————————————————————————————————————

Marching Cubes算法根据一个立方体的8个顶点,判断这8个顶点的每个顶点在等值面的内部还是外部(每个顶点只有“在等值面内”和“在等值面外”这两种状态,设为0和1)从而根据这8个顶点的状态,建立一个包含共256种状态的查找表(根据平面对称性、中心对称性,256种最终降到15种)。

顶点值高于等值在表面的内部,等于等值在表面上,低于等值在表面外。

体元的每个顶点有两种状态,总共有256种,可以制作一个查找表(look up table)

但由于反转状态不变,所以可以减少一半,为128种。

再根据旋转不变形,又可以减少到14种情况。

可以认为这14中类似于基,经过旋转,反转可以得到256种状态对应的结果Triangulated Cubes:

根据每个顶点的状态,我们可以为每类制作一个8位索引Cube Numbering:

索引指向边表,给出了边的交叉情况。

相交边的编码——通过编码记录对应的cube,相交边的编号

二进制:00000010

十进制:2

Table[256]表示哪些边有交点

Table[2]=0x103=0000 0010 0000 0011

表示0,1,9号边上有交点

为了避免每次转化成二进制进行解码,可以直接记录与哪些边有交点,之后直接查表即可。

Table2[256][16]

Table2[2]=(0, 1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

因为每个正方体中最多有1个或4个三角形,所以线性插值就足够了。

2,确定等值面与体元边界的交点

找到含有等值面的体元之后,接下来就是确定等值面与体元边界的交点,体元间的数值都是呈线性变化,求交点时一般采用的是线性插值,如 Case0 中等值面的两个端点 一个在外为( 标记0) ,一个在内 ( 标记为1 ) 则交点为0.5;

3,求等值面的法向量

以上步骤 1,2,3 为实现 MC 算法步骤流程,但利用 VTK ,不需要这么繁琐,主要算法步骤都已经封装到 vtkMarchingCube 类中,使用 vtkMarchingCube 时,需要设置三个参数:

  • SetValue(int i,double value) 设置第i 个等值面的值b,(提醒一下,医学图像中的灰度值范围不是 0-256 而是0-65326,但大部分取值范围都在0-1000)。
  • SetNumberofContours(int number),设置等值面的个数
  • ComputerNormalsOn() 设置计算等值面的法向量,提高渲染质量;

dab9fdfd6e307b681d5c9054c536065e.png

上面这张图显示的就是 vtk 呈像的基本流程,下面是仿照官网写的用面绘制来对图像重建的代码部分:

#include<vtkRenderWindow.h>
#include<vtkRenderWindowInteractor.h>
#include<vtkDICOMImageReader.h>
#include<vtkMarchingCubes.h>
#include<vtkPolyDataMapper.h>
#include<vtkStripper.h>
#include<vtkActor.h>
#include<vtkProperty.h>
#include<vtkCamera.h>
#include<vtkOutlineFilter.h>
#include<vtkOBJExporter.h>
#include<vtkRenderer.h>
#include<vtkMetaImageReader.h>
#include<vtkInteractorStyleTrackballCamera.h>#include<iostream>
#include<string.h>
//需要进行初始化,否则会报错
#include <vtkAutoInit.h> 
#include<vtkRenderingVolumeOpenGL2ObjectFactory.h>
#include<vtkRenderingOpenGL2ObjectFactory.h>using namespace std;
int main()
{///Marching Cube; vtkObjectFactory::RegisterFactory(vtkRenderingOpenGL2ObjectFactory::New());vtkObjectFactory::RegisterFactory(vtkRenderingVolumeOpenGL2ObjectFactory::New());vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();//WINDOW;renWin->AddRenderer(ren);vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();//wininteratcor;iren->SetRenderWindow(renWin);vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();reader->SetDirectoryName("E:/DIcom_Data/DICOM");reader->SetDataByteOrderToLittleEndian();reader->Update();/*vtkDICOMImageReader *reader = vtkDICOMImageReader::New();reader->SetDirectoryName("E:/Coding Pra/VTK/VTK_Examples_StandardFormats_Input_DicomTestImages/DICOM");reader->SetDataByteOrderToLittleEndian();reader->Update();*/cout << "读取数据完毕" << endl;cout << "The width is" << reader->GetWidth() << endl;cout << "The height is" << reader->GetHeight() << endl;cout << "The depth is" << reader->GetPixelSpacing() << endl;cout << "The Output port is" << reader->GetOutputPort() << endl;vtkSmartPointer<vtkMarchingCubes> marchingcube = vtkSmartPointer<vtkMarchingCubes>::New();marchingcube->SetInputConnection(reader->GetOutputPort());//获得读取的数据的点集;marchingcube->SetValue(0, 200);//Setting the threshold;marchingcube->ComputeNormalsOn();//计算表面法向量;vtkSmartPointer<vtkStripper> Stripper = vtkSmartPointer<vtkStripper>::New();Stripper->SetInputConnection(marchingcube->GetOutputPort());//获取三角片vtkSmartPointer<vtkPolyDataMapper> Mapper = vtkSmartPointer<vtkPolyDataMapper>::New();//将三角片映射为几何数据;Mapper->SetInputConnection(Stripper->GetOutputPort());Mapper->ScalarVisibilityOff();//vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();//Created a actor;actor->SetMapper(Mapper);//获得皮肤几何数据actor->GetProperty()->SetDiffuseColor(1, .49, .25);//设置皮肤颜色;actor->GetProperty()->SetSpecular(0.3);//反射率;actor->GetProperty()->SetOpacity(1.0);//透明度;actor->GetProperty()->SetSpecularPower(20);//反射光强度;actor->GetProperty()->SetColor(1, 0, 0);//设置角的颜色;actor->GetProperty()->SetRepresentationToWireframe();//线框;//vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();//Setting the Camera;//camera->SetViewUp(0, 0, -1);//设置相机向上方向;//camera->SetPosition(0, 1, 0);//位置:世界坐标系,相机位置;//camera->SetFocalPoint(0, 0, 0);//焦点,世界坐标系,控制相机方向;//camera->ComputeViewPlaneNormal();//重置视平面方向,基于当前的位置和焦点;vtkSmartPointer<vtkOutlineFilter> outfilterline = vtkSmartPointer<vtkOutlineFilter>::New();outfilterline->SetInputConnection(reader->GetOutputPort());vtkSmartPointer<vtkPolyDataMapper> outmapper = vtkSmartPointer<vtkPolyDataMapper>::New();outmapper->SetInputConnection(outfilterline->GetOutputPort());vtkSmartPointer<vtkActor> OutlineActor = vtkSmartPointer<vtkActor>::New();OutlineActor->SetMapper(outmapper);OutlineActor->GetProperty()->SetColor(0, 0, 0);//线框颜色ren->AddActor(actor);ren->AddActor(OutlineActor);//ren->SetActiveCamera(camera);//设置渲染器的相机;ren->ResetCamera();ren->ResetCameraClippingRange();//camera->Dolly(1.5);//使用Dolly()方法延伸着视平面法向移动相机;ren->SetBackground(1, 1, 1);//设置背景颜色;renWin->SetSize(1000, 600);vtkInteractorStyleTrackballCamera *style = vtkInteractorStyleTrackballCamera::New();iren->SetInteractorStyle(style);renWin->Render();iren->Initialize();iren->Start();vtkSmartPointer<vtkOBJExporter> porter = vtkSmartPointer<vtkOBJExporter>::New();porter->SetFilePrefix("E:/ceshi/aaa/regist_after/polywrite.obj");//重建图像输出porter->SetInput(renWin);porter->Write();return EXIT_SUCCESS;
}

33a9534cf4e61f81f4d5a1ff644aa7f5.png

上面就是 VTK 基于 Marching Cube算法实现的重建效果:

体绘制重建

体绘制时分为两部分:

1,定义 vtkVoluemRayCastMapper 对象

体绘制中最常用的方法 ;vtkVolumeRayCastMapper() 光线投影,体绘制时,首先定义一个Mapper 然后接受两个输入:

  • SetInput(vtkImageDate *) 用于设置输入图像数据;
  • SetVolumeRayCastFunction(vtkVolumeRayCastFunction *) 用于设置光线投影函数类型;
2,利用 vtkVolumeProperty 定义体绘制属性;
  • SetScalarOpacity() 设置灰度不透明函数;
  • SetColor() 颜色传输函数;
3, 定义 vtkVolume 对象接收 Mapper对象和 Property 对象
  • SetMapper()接受 Mapper 对象;
  • SetProperty() 接受 Property 对象;

vtk 中体绘制 核心就是改变 Mapper 和 vtkVolumeRayCastFunction() ,上面中vtkColumeRayCastMapper 只是 VolumeMapper 其中的一种,且投影函数类 vtkVolumeRayCastFunction 一共有三个子类:

  • vtkVolumeRayCastCompositeFunction
  • vtkVolumeRayCasMIPFunction、
  • vtkVolumeRayCastIsosurfaceFunction
  • 因此,其细分的话vtk中的体绘制也不止一种

而下面这个是最常用到的(`vtkVolumeRayCastMapper + vtkVolumeRayCastCompositeFunction

//体绘制#include<vtkRenderWindowInteractor.h>
#include<vtkDICOMImageReader.h>
#include<vtkCamera.h>
#include<vtkActor.h>
#include<vtkRenderer.h>
#include<vtkVolumeProperty.h>
#include<vtkProperty.h>
#include<vtkPolyDataNormals.h>
#include<vtkImageShiftScale.h>
#include "vtkVolumeRayCastMapper.h"
#include<vtkPiecewiseFunction.h>
#include<vtkColorTransferFunction.h>
#include<vtkVolumeRayCastCompositeFunction.h>
#include<vtkRenderWindow.h>
#include<vtkImageCast.h>
#include<vtkVolumeRayCastCompositeFunction.h>
#include<vtkOBJExporter.h>
#include<vtkOutlineFilter.h>
#include<vtkPolyDataMapper.h>#include<vtkInteractorStyleTrackballCamera.h>
#include<vtkRenderingVolumeOpenGL2ObjectFactory.h>
#include<vtkRenderingOpenGL2ObjectFactory.h>
#include<vtkMetaImageReader.h>#include<vtkLODProp3D.h>//体绘制加速//Gpu光照映射
#include<vtkGPUVolumeRayCastMapper.h>#include<iostream>int main()
{vtkObjectFactory::RegisterFactory(vtkRenderingOpenGL2ObjectFactory::New());vtkObjectFactory::RegisterFactory(vtkRenderingVolumeOpenGL2ObjectFactory::New());//定义绘制器;vtkRenderer *aRenderer = vtkRenderer::New();//指向指针;vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();renWin->AddRenderer(aRenderer);vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();iren->SetRenderWindow(renWin);//读取数据;/*vtkDICOMImageReader *reader = vtkDICOMImageReader::New();reader->SetDirectoryName("E:/Coding Pra/VTK/VTK_Examples_StandardFormats_Input_DicomTestImages/DICOM");reader->SetDataByteOrderToLittleEndian();*/vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();reader->SetDirectoryName("E:/DIcom_Data/DICOM");reader->SetDataByteOrderToLittleEndian();//图像数据预处理,类型转换:通过 vtkimageCast 将不同类型数据集转化为 vtk 可以处理的数据集;vtkImageCast *cast_file = vtkImageCast::New();cast_file->SetInputConnection(reader->GetOutputPort());cast_file->SetOutputScalarTypeToUnsignedShort();cast_file->Update();//透明度映射函数定义;vtkPiecewiseFunction *opacityTransform = vtkPiecewiseFunction::New();opacityTransform->AddPoint(0, 0.0);opacityTransform->AddPoint(20, 0.0);opacityTransform->AddPoint(200, 1.0);opacityTransform->AddPoint(300, 1.0);//颜色映射函数定义,梯度上升的vtkColorTransferFunction *colorTransformFunction = vtkColorTransferFunction::New();colorTransformFunction->AddRGBPoint(0.0, 0.0, 0.0, 0.0);colorTransformFunction->AddRGBPoint(64.0, 0.0, 0.0, 0.0);colorTransformFunction->AddRGBPoint(128.0, 1.0, 0.0, 0.0);colorTransformFunction->AddRGBPoint(192.0, 1.0, 0.0, 0.0);colorTransformFunction->AddRGBPoint(255.0, 1.0, 0.0, 0.0);vtkPiecewiseFunction *gradientTransform = vtkPiecewiseFunction::New();gradientTransform->AddPoint(0, 0.0);gradientTransform->AddPoint(20, 2.0);gradientTransform->AddPoint(200, 0.1);gradientTransform->AddPoint(300, 0.1);//体数据属性;vtkVolumeProperty *volumeProperty = vtkVolumeProperty::New();volumeProperty->SetColor(colorTransformFunction);volumeProperty->SetScalarOpacity(opacityTransform);volumeProperty->SetGradientOpacity(gradientTransform);volumeProperty->ShadeOn();//应用volumeProperty->SetInterpolationTypeToLinear();//直线间样条插值;volumeProperty->SetAmbient(0.4);//环境光系数;volumeProperty->SetDiffuse(0.6);//漫反射;volumeProperty->SetSpecular(0.2);volumeProperty->SetSpecularPower(10);//高光强度;计算光照效应;利用 vtkBolumeRayCaseMapper进行计算;//vtkVolumeRayCastMapper *volunemapper = vtkVolumeRayCastMapper::New();//vtkVolumeRayCastCompositeFunction *compositeFunction = vtkVolumeRayCastCompositeFunction::New();//光纤映射类型定义:vtkSmartPointer<vtkVolumeRayCastCompositeFunction> compositecast =vtkSmartPointer<vtkVolumeRayCastCompositeFunction>::New();//Mapper定义,vtkSmartPointer<vtkVolumeRayCastMapper> hiresMapper = vtkSmartPointer<vtkVolumeRayCastMapper>::New();hiresMapper->SetInputData(cast_file->GetOutput());hiresMapper->SetVolumeRayCastFunction(compositecast);vtkSmartPointer<vtkLODProp3D> prop = vtkSmartPointer<vtkLODProp3D>::New();prop->AddLOD(hiresMapper,volumeProperty,0.0);////volunemapper->SetVolumeRayCastFunction(compositeFunction);//载入体绘制方法;//volunemapper->SetInputConnection(cast_file->GetOutputPort());//vtkFixedPointVolumeRayCastMapper *fixedPointVolumeMapper = vtkFixedPointVolumeRayCastMapper::New()//fixedPointVolumeMapper->SetInput()vtkVolume *volume = vtkVolume::New();volume->SetMapper(hiresMapper);volume->SetProperty(volumeProperty);//设置体属性;double volumeView[4] = { 0,0,0.5,1 };vtkOutlineFilter *outlineData = vtkOutlineFilter::New();//线框;outlineData->SetInputConnection(reader->GetOutputPort());vtkPolyDataMapper *mapOutline = vtkPolyDataMapper::New();mapOutline->SetInputConnection(outlineData->GetOutputPort());vtkActor *outline = vtkActor::New();outline->SetMapper(mapOutline);outline->GetProperty()->SetColor(0, 0, 0);//背景纯黑色;aRenderer->AddVolume(volume);aRenderer->AddActor(outline);aRenderer->SetBackground(1, 1, 1);aRenderer->ResetCamera();//重设相机的剪切范围;aRenderer->ResetCameraClippingRange();renWin->SetSize(800, 800);renWin->SetWindowName("测试");vtkRenderWindowInteractor *iren2 = vtkRenderWindowInteractor::New();iren2->SetRenderWindow(renWin);//设置相机跟踪模式vtkInteractorStyleTrackballCamera *style = vtkInteractorStyleTrackballCamera::New();iren2->SetInteractorStyle(style);renWin->Render();iren2->Initialize();iren2->Start();vtkOBJExporter *porter = vtkOBJExporter::New();porter->SetFilePrefix("E:/ceshi/aaa/regist_after/esho.obj");porter->SetInput(renWin);porter->Write();porter->Update();return EXIT_SUCCESS;}

0c8404965dbab9c8abcab0cd04762657.png

上面是体绘制的结果,相对来说体绘制需要计算资源更大些, vtk 在这方面有所考虑,提供了vtKGPUVolumeRayCastMapper GUP 加速的光线投射算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/605206.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

随机森林(Random Forest)

随机森林&#xff08;Random Forest&#xff09;是一种集成学习方法&#xff0c;通过组合多个决策树来提高模型的性能和鲁棒性。随机森林在每个决策树的训练过程中引入了随机性&#xff0c;包括对样本和特征的随机选择&#xff0c;以提高模型的泛化能力。以下是随机森林的基本原…

本地部署 gemini-openai-proxy,使用 Google Gemini 实现 Openai API

本地部署 gemini-openai-proxy&#xff0c;使用Google Gemini 实现 Openai API 0. 背景1. 申请 Google Gemini API key2. (Optional)Google Gemini 模型说明3. gemini-openai-proxy Github 地址4. 本地部署 gemini-openai-proxy5. 测试 0. 背景 使用 Google Gemini 实现 Opena…

Java 之 CAS(CompareAndSwap)底层原理详解

目录 一. 前言 二. CAS 底层原理 2.1. 代码实例 2.2. 源码分析 2.3. 底层汇编 2.4. ABA 问题 三. 总结 3.1. CAS 缺点 3.2. CAS 会导致 ABA 问题 一. 前言 CAS 的全称是 Compare-And-Swap&#xff0c;它是 CPU 并发原语。它的功能是判断内存某个位置的值是否为预期值。…

MySQL 8.0 开关 Redo Logging

一 前言 前几天有客户测试使用云数据库的时候提出 要禁止mydumper 关闭redo log的操作 (说白了就是导入数据时保持MySQL 实例的redo logging功能)&#xff0c; 这才想起 在 MySQL 8.0.21 版本中&#xff0c;开启了一个新特性 “Redo Logging 动态开关”。 在新实例导数据的场…

【IPC通信--消息队列】

消息队列&#xff08;也叫做报文队列&#xff09;是一个消息的链表。可以把消息看作一个记录&#xff0c;具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息&#xff1b;对消息队列有读权限的进程则可以从消息队列中读走消息…

linux删除操作,删除文件夹,删除文件夹下面所有文件,删除文件,删除文件中内容等命令

在Linux中&#xff0c;你可以使用以下命令来执行删除操作&#xff1a; 删除文件夹&#xff1a; rm -r <文件夹路径>例如&#xff0c;要删除名为"folder"的文件夹&#xff0c;可以运行&#xff1a; rm -r folder删除文件夹下的所有文件&#xff1a; rm -r <文…

Debezium发布历史54

原文地址&#xff1a; https://debezium.io/blog/2019/04/18/hello-debezium/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. Debezium 的团队不断壮大 2019 年 4 月 18 日 作者&#xff1a; 克里斯克兰福德 社…

Django5+DRF序列化

概述 本教程将介绍如何创建一个简单的粘贴板代码高亮 Web API。在此过程中&#xff0c;它将介绍构成 REST 框架的各种组件&#xff0c;让你全面了解所有组件是如何组合在一起的。 本教程相当深入&#xff0c;因此在开始学习之前&#xff0c;你可能需要先吃一块饼干&#xff0…

eval() 函数的理解

eval() 函数是 Python 内置的一个函数&#xff0c;它用于执行以字符串形式表示的 Python 表达式。它将字符串当作有效的 Python 表达式进行解析和执行&#xff0c;并返回表达式的结果。 语法&#xff1a; eval(expression, globalsNone, localsNone)expression: 要被解析和执…

[C#]Onnxruntime部署Chinese CLIP实现以文搜图以文找图功能

【官方框架地址】 https://github.com/OFA-Sys/Chinese-CLIP 【算法介绍】 在当今的大数据时代&#xff0c;文本信息处理已经成为了计算机科学领域的核心议题之一。为了高效地处理海量的文本数据&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术应运而生。而在诸多N…

电子实验室设备:从零开始配置实验室(一)

本文译自 Electronics Lab Equipment: Kitting out a Lab from Scratch 随着多次国际迁徙以及在几家公司&#xff08;或其分支机构&#xff09;工作&#xff0c;尤其是在没有强大电子工程团队的情况下&#xff0c;我不得不为自己和客户设置多个电子实验室。那些计划进行内部测试…

什么是缓存、为什么要用缓存

缓存是将一些频繁需要访问的数据临时存储在高速存储器中&#xff0c;以便提高数据访问的速度和效率的一种技术。 使用缓存的原因主要有以下几点&#xff1a; 提高访问速度&#xff1a;缓存可以将数据存储在位于CPU或内存之间的高速存储器中&#xff0c;相比于从硬盘或网络中读…

人教版初中数学八年级上册“阅读与思考”《数据波动程度的几种度量》教学设计

教学目标 1. 了解方差、极差、标准差、平均差的定义和计算公式。 2. 会用方差、极差、标准差、平均差计算公式来比较两组数据的波动大小。 3.经历探索方差、极差、标准差、平均差公式的形成过程和应用过程。 重难点分析 教学重点&#xff1a;体会数据波动中几种程度的度量…

gin使用jwt登录验证

使用github.com/dgrijalva/jwt-go包,gihub地址:https://github.com/dgrijalva/jwt-go 安装包 go get -u github.com/dgrijalva/jwt-go简单封装生成token、验证token有效、通过Authorization解析token三个函数 models/jwt.go package modelsimport ("net/http"&quo…

HCIA-Datacom题库(自己整理分类的)_08_FTP协议【8道题】

一、单选 1.在使用FTP协议升级路由器软件时&#xff0c;传输模式应该选用___ 二进制模式 字节模式 文字模式 流字节模式 解析&#xff1a;二进制模式&#xff1a;在数据连接中传输&#xff0c;不对数据进行任何处理&#xff0c;不需要转换或格式化就可以传输字符。 2.以…

网页设计与制作web前端设计html+css+js成品。电脑网站制作代开发。vscodeDrea 【企业公司宣传网站(HTML静态网页项目实战)附源码】

网页设计与制作web前端设计htmlcssjs成品。电脑网站制作代开发。vscodeDrea 【企业公司宣传网站&#xff08;HTML静态网页项目实战&#xff09;附源码】 https://www.bilibili.com/video/BV1Hp4y1o7RY/?share_sourcecopy_web&vd_sourced43766e8ddfffd1f1a1165a3e72d7605

【C++】STL 算法 ⑥ ( 二元谓词 | std::sort 算法简介 | 为 std::sort 算法设置 二元谓词 排序规则 )

文章目录 一、二元谓词1、二元谓词简介2、 std::sort 算法简介3、 代码示例 - 为 std::sort 算法设置 二元谓词 排序规则 一、二元谓词 1、二元谓词简介 " 谓词 ( Predicate ) " 是一个 返回 布尔 bool 类型值 的 函数对象 / 仿函数 或 Lambda 表达式 / 普通函数 , …

逆置算法和数组循环移动算法

元素逆置 概述&#xff1a;其实就是将 第一个元素和最后一个元素交换&#xff0c;第二个元素和倒数第二个元素交换&#xff0c;依次到中间位置。用途&#xff1a;可用于数组的移动&#xff0c;字符串反转&#xff0c;链表反转操作&#xff0c;栈和队列反转等操作。 逆置图解 …

2024年1月7日15:09:50

2024年1月7日15:09:55复习&#xff1a;我今天学了有价值的东西&#xff0c;那就是在瓦罗兰特拿到了三杀 2024年1月7日15:11:10学习了如何使用vivopad2的键盘 可以稍微用一下 2024年1月7日15:17:58 学习一个编程的题目 2024年1月7日15:31:27不用机械键盘打字效率就是比不用低…

深入理解堆(Heap):一个强大的数据结构

. 个人主页&#xff1a;晓风飞 专栏&#xff1a;数据结构|Linux|C语言 路漫漫其修远兮&#xff0c;吾将上下而求索 文章目录 前言堆的实现基本操作结构体定义初始化堆&#xff08;HeapInit&#xff09;销毁堆&#xff08;HeapDestroy&#xff09; 重要函数交换函数&#xff08;…