当前位置: 首页 > news >正文

Java 数据结构篇-实现双链表的核心API

🔥博客主页: 小扳_-CSDN博客
❤感谢大家点赞👍收藏⭐评论✍
 

 

 

文章目录

        1.0 双链表的说明

        1.1 双链表 - 创建

        1.2 双链表 - 根据索引查找节点

        1.3 双链表 - 根据索引插入节点

        1.4 双链表 - 头插节点

        1.5 双链表 - 尾插

        1.6 双链表 - 根据索引来删除节点

        1.7 头删节点

        1.8 尾删节点

        1.9 实现迭代器循环

        2.0 双链表完整的实现代码

        3.0 环形双链表的说明

        3.1 环形双链表 - 创建

        3.2 环形双链表 - 头插节点

        3.3 环形双链表 - 尾插节点

        3.4 环形双链表 - 头删节点

        3.5 环形双链表 - 尾删节点

        3.6 环形链表 - 根据值来删除节点

        4.0 环形双链表完整的实现代码


        1.0 双链表的说明

        双链表是一种数据结构,其中每个节点包含两个指针一个指向前一个节点一个指向后一个节点。双链表可以在任意位置插入或删除节点,而不需要像单链表那样遍历整个链表来找到需要操作的位置。双链表可以用于实现栈、队列、以及其他需要快速插入和删除操作的数据结构。由于每个节点包含两个指针,双链表的内存占用量通常比单链表更大

        1.1 双链表 - 创建

        把双链表封装成一个类,类中还需要封装一个节点类 Node,该节点类的成员有指向前一个节点的变量 Node prev,值 value ,指向后一个节点的变量 Node next

代码如下:

public class MyDoubleLists{private final Node hand;private final Node tail;private static class Node {public Node prev;public Node next;public int value;public Node(Node prev, int value, Node next) {this.prev = prev;this.next = next;this.value = value;}}public MyDoubleLists() {hand = new Node(null,0,null);tail = new Node(hand,-1,null);hand.next = tail;tail.prev = hand;}}

         注意外部类中,还需要定义头节点,尾节点,再利用外部类的构造器中就可以完成对头尾节点的初始化了。内部类中的节点类建议用静态来修饰。

        1.2 双链表 - 根据索引查找节点

        由于这个方法可以为其他几个方法提供服务,因此,把这个方法独立出来。实现思路为:开始的节点应为 hand,循环终止条件为:p == tail 当指向尾节点的那一刻就该结束循环了。还要加一个变量 i = -1 ,每一次循环结束要进行 i++ ,当 i == index 时,找到了该索引的节点,返回该节点即可,若循环结束还是没找到,就得返回 null

代码如下:

    //根据索引查找节点private Node findNode(int index) {int i = -1;for (Node p = hand; p !=tail ; p = p.next,i++){if (i == index) {return p;}}return null;}

        这个方法一般不会对外开发,因此,加上 private 来修饰,当 i == -1 时,返回的时头节点,所以一开始的节点为 hand 。对外是索引从 0 开始才会存储值的,对于头节点存储什么值是不关心的。

        1.3 双链表 - 根据索引插入节点

         根据索引插入节点,提前需要准备好该节点的前一个节点 prev、该节点的后一个节点 next 。通过以上已经实现的方法来找到插入位置的前一个结点,prev = findNode(index - 1),后一个节点也就可以找到了,next = prev.next

代码如下:

    //根据索引插入节点public void insert(int index, int value) {Node p = findNode(index - 1);if (p == null){throw new RuntimeException("用索引访问失败");}Node prev = p;Node next = prev.next;Node insertNode = new Node(prev, value,next);prev.next = insertNode;next.prev = insertNode;}

        prev.next 指向新的节点next.prev 指向上一个节点。新的节点的头节点的引用为 prev,尾节点为 next 。 

         1.4 双链表 - 头插节点

        其实这个方法就比较简单了,这个就是根据索引 0 来插入节点的,就是一个索引等于0的特例,所以可以直接调用已经实现的 insert(0,int value) 方法。

代码如下:

    //头插节点public void addFirst(int value) {insert(0,value);}

         1.5 双链表 - 尾插

        对尾部的操作是双链表的一个很大的优势,对尾部的查询、增加节点、删除节点效率都很快,因为对尾节点是有记录的,就不用从头开始来查找尾部节点了,直接可以得到。

        实现方法的思路为:需要找到插入的前一个节点插入的后一个节点肯定是尾节点,所以,可以通过   prev =  tail.prev,来找到插入的前一个节点。

代码如下:

    //尾插节点public void addLast(int value) {Node lats = tail;Node prev = lats.prev;Node addNode = new Node(prev,value,lats);prev.next = addNode;lats.prev = addNode;}

        新的节点的前一个节点为 prev ,后节点为 tail,prev.next 与 tail.prev 就要更改为指向新的节点了。

        1.6 双链表 - 根据索引来删除节点

        先通过已经实现的 findNode() 方法来找到该索引的节点,还有找到删除该节点的前一个节点与后一个节点。

代码如下:

    //根据索引来删除节点public void remove(int index) {Node prev = findNode(index - 1);if (prev == null) {throw new RuntimeException("用索引来删除数据失败!");}Node remove = prev.next;if (remove == tail) {throw new RuntimeException("用索引来删除数据失败!");}Node next = remove.next;prev.next = next;next.prev = next;}

         接着就可以将要删除的前一个节点指向要删除的节点后一个节点,但是考虑两种情况,第一种,当要删除的节点没找到,就要抛出异常了。第二种,当发现要删除的节点为 tail 时需要抛出异常,总不能自己把自己的尾巴 "切了吧" 然而不用考虑是否把头节点删除,因为要删除的节点总是拿不到头节点。

         1.7 头删节点

        当索引为0时,就是头删,是 remove(0) 方法的一个特例。可以直接来调用根据索引来删除节点的方法。

代码如下:

    //头删节点public void removeFirst() {remove(0);}

         1.8 尾删节点

        双链表尾删的效率是很高的,因为对尾节点是有记录的。

代码如下:

    //尾删节点public void removeLast() {Node remove = tail.prev;if (remove == hand){throw new RuntimeException();}Node prev = remove.prev;prev.next = tail;tail.prev = prev;}

        需要找到三个节点,要删除的节点、删除节点的前一个节点、还有尾节点。需要注意的是,判断要删除的节点为头节点,需要抛出异常,总不能自己把自己的 " 头部 " 给切了吧。

         1.9 实现迭代器循环

        这个完成 Iterable 接口,创建新的该接口子类对象,重写两个方法即可。

代码如下:

    //实现迭代器循环@Overridepublic Iterator<Integer> iterator() {return new Iterator<Integer>() {Node p = hand.next;@Overridepublic boolean hasNext() {return p != tail;}@Overridepublic Integer next() {int value = p.value;p = p.next;return value;}};}

        需要注意的是,头节点的值是不用在乎的,所以遍历开始为 hand.next ,循环结束条件为,p == tail,遍历到尾节点就要终止了。

        2.0 双链表完整的实现代码

 

import java.util.Iterator;public class MyDoubleLists implements Iterable<Integer>{private final Node hand;private final Node tail;private static class Node {public Node prev;public Node next;public int value;public Node(Node prev, int value, Node next) {this.prev = prev;this.next = next;this.value = value;}}public MyDoubleLists() {hand = new Node(null,0,null);tail = new Node(hand,-1,null);hand.next = tail;tail.prev = hand;}//根据索引查找节点private Node findNode(int index) {int i = -1;for (Node p = hand; p !=tail ; p = p.next,i++){if (i == index) {return p;}}return null;}//根据索引插入节点public void insert(int index, int value) {Node p = findNode(index - 1);if (p == null){throw new RuntimeException("用索引访问失败");}Node prev = p;Node next = prev.next;Node insertNode = new Node(prev, value,next);prev.next = insertNode;next.prev = insertNode;}//头插节点public void addFirst(int value) {insert(0,value);}//尾插节点public void addLast(int value) {Node lats = tail;Node prev = lats.prev;Node addNode = new Node(prev,value,lats);prev.next = addNode;lats.prev = addNode;}//根据索引来删除节点public void remove(int index) {Node prev = findNode(index - 1);if (prev == null) {throw new RuntimeException("用索引来删除数据失败!");}Node remove = prev.next;if (remove == tail) {throw new RuntimeException("用索引来删除数据失败!");}Node next = remove.next;prev.next = next;next.prev = next;}//头删节点public void removeFirst() {remove(0);}//尾删节点public void removeLast() {Node remove = tail.prev;if (remove == hand){throw new RuntimeException();}Node prev = remove.prev;prev.next = tail;tail.prev = prev;}//根据索引来查询数据public int get(int index) {Node find = findNode(index);if (find == null){throw new RuntimeException("根据该索引找不到数据");}return find.value;}//实现迭代器循环@Overridepublic Iterator<Integer> iterator() {return new Iterator<Integer>() {Node p = hand.next;@Overridepublic boolean hasNext() {return p != tail;}@Overridepublic Integer next() {int value = p.value;p = p.next;return value;}};}}

        3.0 环形双链表的说明

        环形双链表是一种数据结构,它类似于双向链表,但是链表的最后一个节点指向第一个节点,形成一个环形结构。简单来说,先对比与一般的双链表,环形双链表就是头尾节点都是同一个节点

        3.1 环形双链表 - 创建

        把环形双链表看成一个对象,该类中需要封装一个节点的内部类,对外不开放的,需要用限制修饰符来修饰。外部类中的成员变为 sentinel ,即作为头节点,也作为尾节点

代码如下:

public class MyAnnularDoubleList{private final Node sentinel;private static class Node {public Node prev;public int value;public Node next;public Node(Node prev, int value, Node next) {this.prev = prev;this.value = value;this.next = next;}}public MyAnnularDoubleList() {sentinel = new Node(null,0,null);sentinel.prev = sentinel;sentinel.next = sentinel;}}

        在创建环形双链表时,在用无参构造器就可以先把 sentinel 初始化了。

        3.2 环形双链表 - 头插节点

        根据 next =  sentinel.next 就可以得到插入点的下一个节点,就可以把新节点的指向的前一个节点来指向 sntinel,新节点的指向后一个节点来指向 next

        这里需要考虑一种情况,假设,该环形双链表中就只有一个 sentinel 节点,以上阐述的思路还能不能用呢?答案时可以的,如果实在理解不了的话,可以把一个 sentinel 节点,想象成两个 sentinel 节点,效果都是一样的,都是指向自己嘛。

代码如下:

    //头插节点public void addFirst(int value) {Node hand = sentinel;Node tail = sentinel.next;Node addNode = new Node(hand,value,tail);hand.next = addNode;tail.prev = addNode;}

        3.3 环形双链表 - 尾插节点

        根据 prev = sentinel.prev 来找到插入节点的前一个的节点,插入节点的后一个节点就是 sentinel ,新节点的指向前的节点为 prev,新节点的指向后的节点为 sentinel ,接着 prev.next 指向新节点,sentinel.prev 指向新节点。

代码如下:

    //尾插节点public void addLast(int value) {Node prev = sentinel.prev;Node next = sentinel;Node addNode = new Node(prev,value,next);prev.next = addNode;next.prev = addNode;}

        同理,不需要额外考虑当节点只有一个时,以上代码依旧可以实现尾插节点。

        3.4 环形双链表 - 头删节点

        根据 remove = sentinel.next ,可以得到需要删除的节点,再由 next = remove.next,得到删除节点的后一个节点,这样三个节点后已知了,santinel.next 指向 next ,next.prev 指向sentinel ,剩下的没有被引用的节点(对象),会被 JVM 自动回收

代码如下:

    //头删节点public void removeFirst() {Node remove = sentinel.next;if (remove == sentinel) {throw new RuntimeException("删除失败!");}Node next = remove.next;sentinel.next = next;next.prev = sentinel;}

        需要注意的是,当删除的节点为 sentinel 需要抛出异常,但是个人感觉不加判断也可以,sentinel 根本不会被删除,即使只有 sentinel 一直被删除。

        3.5 环形双链表 - 尾删节点

        根据 remove = sentinel.prev 得到需要删除的节点,通过 prev = remove.prev 得到需要删除的前一个节点,prev.next 指向 sentinelsentinel.prev 指向 prev 即可。

代码如下:

    //尾删节点public void removeLast() {Node remove = sentinel.prev;Node prev = remove.prev;prev.next = sentinel;sentinel.prev = prev;}

        同样的,当删除的节点为 sentinel 需要抛出异常,但是个人感觉不加判断也可以,sentinel 根本不会被删除,即使只有 sentinel 一直被删除。

         3.6 环形链表 - 根据值来删除节点

        先独立一个方法,根据值来查询节点,一开始的循环节点为 sentinel.next ,对于 sentinel 里面的值是什么根本不在乎的。循环终止条件为:p == sentinel 已经转完一圈了。找到就返回该节点,找不到就返回 null 。删除的原理是一样的,得先找到三个节点,然后把前后节点直接关联起来。

代码如下:

    //根据值来删除节点private Node findValue (int value) {for (Node p = sentinel.next; p != sentinel; p = p.next) {if (p.value == value) {return p;}}return null;}public void removeValue (int value) {Node remove = findValue(value);if (remove == null) {throw new RuntimeException("找不到该数据来删除相对应的节点");}Node prev = remove.prev;Node next = remove.next;prev.next = next;next.prev = prev;}

        需要注意的是,当接收到的节点为 null 时,需要抛出异常,找不到对应该值的节点。

        4.0 环形双链表完整的实现代码

import java.util.Iterator;public class MyAnnularDoubleList implements Iterable<Integer>{private final Node sentinel;private static class Node {public Node prev;public int value;public Node next;public Node(Node prev, int value, Node next) {this.prev = prev;this.value = value;this.next = next;}}public MyAnnularDoubleList() {sentinel = new Node(null,0,null);sentinel.prev = sentinel;sentinel.next = sentinel;}//头插节点public void addFirst(int value) {Node hand = sentinel;Node tail = sentinel.next;Node addNode = new Node(hand,value,tail);hand.next = addNode;tail.prev = addNode;}//尾插节点public void addLast(int value) {Node prev = sentinel.prev;Node next = sentinel;Node addNode = new Node(prev,value,next);prev.next = addNode;next.prev = addNode;}//头删节点public void removeFirst() {Node remove = sentinel.next;if (remove == sentinel) {throw new RuntimeException("删除失败!");}Node next = remove.next;sentinel.next = next;next.prev = sentinel;}//尾删节点public void removeLast() {Node remove = sentinel.prev;Node prev = remove.prev;prev.next = sentinel;sentinel.prev = prev;}//根据值来删除节点private Node findValue (int value) {for (Node p = sentinel.next; p != sentinel; p = p.next) {if (p.value == value) {return p;}}return null;}public void removeValue (int value) {Node remove = findValue(value);if (remove == null) {throw new RuntimeException("找不到该数据来删除相对应的节点");}Node prev = remove.prev;Node next = remove.next;prev.next = next;next.prev = prev;}//实现迭代器@Overridepublic Iterator<Integer> iterator() {return new Iterator<Integer>() {Node p = sentinel.next;@Overridepublic boolean hasNext() {return p != sentinel;}@Overridepublic Integer next() {int value = p.value;p = p.next;return value;}};}
}

相关文章:

Java 数据结构篇-实现双链表的核心API

&#x1f525;博客主页&#xff1a; 小扳_-CSDN博客 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 双链表的说明 1.1 双链表 - 创建 1.2 双链表 - 根据索引查找节点 1.3 双链表 - 根据索引插入节点 1.4 双链表 - 头插节点 1.5 双链表 - 尾插 1.6 双链表 - 根据索引来…...

电脑如何截屏?一起来揭晓答案!

在数字时代&#xff0c;截屏已经成为我们日常生活和工作中的必备技能。无论是为了捕捉有趣的网络瞬间&#xff0c;保存重要信息&#xff0c;还是为了协作和教育&#xff0c;电脑截屏都是一个强大而方便的工具。本文将介绍三种电脑如何截屏的方法&#xff0c;以满足各种需求&…...

【实战-08】flink 消费kafka自定义序列化

目的 让从kafka消费出来的数据&#xff0c;直接就转换成我们的对象 mvn pom <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information …...

深入浅出 Django 异步编程

随着 Web 应用对性能的要求日益提高&#xff0c;异步编程成为了提升响应速度、提高系统吞吐量的重要手段。Django 作为一个成熟的 Python Web 框架&#xff0c;自 3.1 版本开始支持了异步编程。在本文中&#xff0c;我们将探讨 Django 异步编程的关键概念&#xff0c;并提供实际…...

力扣 138. 随机链表的复制

文章目录 1.解题思路2.代码实现 1.解题思路 在原先链表的每一个元素后面插入一个与前一个相同val的值的结点,然后由于是在原链表进行的操作&#xff0c;因此找每个random就变得很方便直接访问即可&#xff0c;此题目的精髓是cur1->randomp->random->next,看懂这串代码…...

STM32外部中断大问题

问题&#xff1a;一直进入中断&#xff0c;没有触发信号&#xff0c;也一直进入。 描述&#xff1a;开PA0为外部中断&#xff0c;刚刚很好&#xff0c;一个触发信号一个中断&#xff0c;中断函数没有丢&#xff0c;也没有抢跑&#xff0c;开PA1为外部中断也是&#xff0c;都很好…...

FPGA配置采集AR0135工业相机,提供2套工程源码和技术支持

目录 1、前言免责声明 2、AR0135工业相机简介3、我这里已有的 FPGA 图像处理解决方案4、设计思路框架AR0135配置和采集图像缓存视频输出 5、vivado工程1–>Kintex7开发板工程6、vivado工程1–>Zynq7100开发板工程7、上板调试验证8、福利&#xff1a;工程代码的获取 1、前…...

KubeSphere v3.4.0 部署K8S Docker + Prometheus + grafana

KubeSphere v3.4.0 部署K8S 1、整体思路2、修改linux主机名3、 离线安装3.1 问题列表3.2 执行命令成功列表 1、整体思路 将KubeSphere v3.4.0 安装包传输到其中一台机器修改Linux主机名&#xff08;选取3台&#xff0c;修改为master01、master02、master03&#xff09;安装官方…...

Codeforces Round 908 (Div. 2)题解

目录 A. Secret Sport 题目分析: B. Two Out of Three 题目分析: C. Anonymous Informant 题目分析: A. Secret Sport 题目分析: A,B一共打n场比赛&#xff0c;输入一个字符串由A和‘B’组成代表A赢或者B赢&#xff08;无平局&#xff09;&#xff0c;因为题目说明这个人…...

Redis笔记 Redis主从同步

文章目录 Redis主从搭建主从架构主从数据同步原理全量同步增量同步repl_backlog原理 主从同步优化小结 Redis主从 搭建主从架构 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离。 主从数据…...

数据结构-Prim算法构造无向图的最小生成树

引子&#xff1a; 无向图如果是一个网&#xff0c;那么它的所有的生成树中必有一颗生成树的边的权值之和是最小的&#xff0c;我们称 这颗权值和最小的树为&#xff1a;“最小生成树”&#xff08;MST&#xff09;。 其中&#xff0c;一棵树的代价就是树中所有权值之和。 而…...

MFC串口通信(SerialPort)

目录 1、SerialPort类的介绍和使用&#xff1a; &#xff08;1&#xff09;、SerialPort类的功能介绍 &#xff08;2&#xff09;、SerialPort类提供接口函数的介绍 1&#xff09;、InitPort函数 2&#xff09;、控制串口监视线程函数 3&#xff09;、获取事件&#xff0c…...

Vim基本使用操作

前言&#xff1a;作者也是初学Linux&#xff0c;可能总结的还不是很到位 Linux修炼功法&#xff1a;初阶功法 ♈️今日夜电波&#xff1a;美人鱼—林俊杰 0:21━━━━━━️&#x1f49f;──────── 4:14 …...

【深蓝学院】手写VIO第8章--相机与IMU时间戳同步--作业

0. 题目 1. T1 逆深度参数化时的特征匀速模型的重投影误差 参考常鑫助教的答案&#xff1a;思路是将i时刻的观测投到world系&#xff0c;再用j时刻pose和外参投到j时刻camera坐标系下&#xff0c;归一化得到预测的二维坐标&#xff08;这里忽略了camera的内参&#xff0c;逆深…...

Naocs配置中心配置映射List、Map、Map嵌套List等方式

一、配置映射List 1、常规逐个配置方式,示例如下: 代码: @Data @Configuration @ConfigurationProperties(prefix = "list-json-str") public class ConfListByJsonStr implements Serializable, InitializingBean {@ApiModelProperty("映射结果集")…...

如何通过CRM系统进行销售机会管理?

销售机会管理是在销售过程中对潜在客户的精细化管理&#xff0c;销售机会管理的本质是公司用于管理销售机会通用的工具和方法。对于希望建立长期客户关系的现代销售团队来说&#xff0c;CRM客户管理系统是必不可少的工具。那企业如何通过CRM系统进行销售机会管理&#xff1f; …...

解决idea启动tomcat控制台中文乱码

#1.tomcat日志中文乱码# 如图这种情况&#xff0c;一般在idea用tomcat跑一个web项目启动后tomcat日志在控制台打印出来会出现中文乱码的情况 解决方案1&#xff1a;tomcat的日志配置文件的编码修改&#xff0c;找到tomcat安装目录conf下的logging.properties&#xff0c;encod…...

vscode + cmake + opencv example

nice try on macos CMakeLists.txt cmake_minimum_required(VERSION 3.20) #添加OPENCV库 #指定OpenCV版本&#xff0c;代码如下 #find_package(OpenCV 3.3 REQUIRED) #如果不需要指定OpenCV版本&#xff0c;代码如下 find_package(OpenCV REQUIRED)#添加OpenCV头文件 includ…...

day57【动态规划】647.回文子串 516.最长回文子序列

文章目录 647. 回文子串516.最长回文子序列 647. 回文子串 力扣题目链接 代码随想录讲解 题意&#xff1a;给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的…...

分享vmware和Oracle VM VirtualBox虚拟机的区别,简述哪一个更适合我?

VMware和Oracle VM VirtualBox虚拟机的区别主要体现在以下几个方面&#xff1a; 首先两种软件的安装使用教程如下&#xff1a; 1&#xff1a;VMware ESXI 安装使用教程 2&#xff1a;Oracle VM VirtualBox安装使用教程 商业模式&#xff1a;VMware是一家商业公司&#xff0c;而…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...