经验分享|作为程序员之后了解到的算法知识

news2025/1/12 7:58:10

欢迎关注博主 六月暴雪飞梨花 或加入【六月暴雪飞梨花】一起学习和分享Linux、C、C++、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。
在这里插入图片描述

一个程序员一生中可能会邂逅各种各样的算法,但总有那么几种,是作为一个程序员一定会遇见且大概率需要掌握的算法。今天就来聊聊这些十分重要的“必抓!”算法吧~

一 引言

1.1 算法的定义

算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令。它代表着用系统的方法描述解决问题的策略机制。算法能够处理一定规范的输入,在有限时间内获得所要求的输出。

1.2 算法的特征

一个算法具有以下四个重要的特征:有穷性(Finiteness)、确切性(Definiteness)、输入和输出项 (Input/Ouput)、可行性(Effectiveness)。

1.3 算法的分类

算法可以根据不同的标准进行分类。

  • 算法宏观泛义分类:有限确定性算法、有限不定性算法和无限算法。
  • 算法设计原理分类:搜索算法、排序算法、图算法、动态规划算法、回溯算法。
  • 算法的使用用途分类:数值算法、字符串算法、图像处理算法、机器学习算法、并行计算算法。

1.4 算法的描述

在计算机中,如何描述算法,主要有自然语言,流程图,代码等。

在流程图中,描述算法可使用如下的标识符号。
在这里插入图片描述

在代码中的算法可以描述为如下

public class RecursionExample {  
    public static void main(String[] args) {  
        int n = 5;  
        int result = factorial(n);  
        System.out.println("Factorial of " + n + " is " + result);  
    }  
  
    public static int factorial(int n) {  
        if (n == 0) {  
            return 1;  
        } else {  
            return n * factorial(n - 1);  
        }  
    }  
}

使用动态图演示如下:
在这里插入图片描述

二 常见算法介绍

提示:介绍常见的排序算法,查找算法、图论算法和字符串算法等等

2.1 分治法

【基本思想】
分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。

【解题思路】
分解->求解->合并

【实例解析】
快速排序(Quick Sort):选取基准数(比如第一个),比我小的往前排,比我大的往后排。

public class QuickSort {  
  
    public static void quickSort(int[] arr, int low, int high) {  
        if (low < high) {  
            // pi 是分区索引,arr[pi] 的位置已经确定了  
            int pi = partition(arr, low, high);  
  
            // 通过递归调用,分别对pi的左右两部分进行排序  
            quickSort(arr, low, pi - 1);  
            quickSort(arr, pi + 1, high);  
        }  
    }  
  
    // 这个函数用来找出数组中最大元素的位置,并返回该位置  
    public static int partition(int[] arr, int low, int high) {  
        // 选择最右边的元素作为基准  
        int pivot = arr[high];   
        int i = (low - 1); // 指向最小元素的指针  
        for (int j = low; j < high; j++) {  
            // 如果当前元素小于或等于 pivot  
            if (arr[j] <= pivot) {  
                i++;  
  
                // 交换 arr[i] 和 arr[j]  
                int temp = arr[i];  
                arr[i] = arr[j];  
                arr[j] = temp;  
            }  
        }  
  
        // 交换 arr[i+1] 和 arr[high] (或者基准)  
        int temp = arr[i + 1];  
        arr[i + 1] = arr[high];  
        arr[high] = temp;  
  
        return i + 1;  
    }  
  
    public static void main(String args[]) {  
        int arr[] = {10, 7, 8, 9, 1, 5};  
        int n = arr.length;  
  
        quickSort(arr, 0, n - 1);  
  
        System.out.println("排序后的数组:");  
        for (int i = 0; i < n; ++i) {  
            System.out.print(arr[i] + " ");  
        }  
        System.out.println();  
    }  
}

2.2 贪心法

【基本思想】
局部最优解,可能得到整体最优解或是最优解的近似解。

【解题思路】
在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。

【实例解析】
Prim算法(最小生成树算法之一,还有一个为Kruskal算法)。

import java.util.Arrays;  
  
class Graph {  
    private static final int INF = Integer.MAX_VALUE;  
    private int numVertices;  
    private int[][] adjacencyMatrix;  
  
    public Graph(int numVertices) {  
        this.numVertices = numVertices;  
        adjacencyMatrix = new int[numVertices][numVertices];  
        for (int[] row : adjacencyMatrix)  
            Arrays.fill(row, INF);  
    }  
  
    public void addEdge(int src, int dest, int weight) {  
        adjacencyMatrix[src][dest] = weight;  
        adjacencyMatrix[dest][src] = weight;  
    }  
  
    private int getMinVertex(boolean[] mstSet, int[] key) {  
        int minKey = INF;  
        int vertex = -1;  
        for (int i = 0; i < numVertices; i++) {  
            if (!mstSet[i] && key[i] < minKey) {  
                minKey = key[i];  
                vertex = i;  
            }  
        }  
        return vertex;  
    }  
  
    public void primMST() {  
        boolean[] mstSet = new boolean[numVertices];  
        int[] key = new int[numVertices];  
        int[] parent = new int[numVertices];  
  
        Arrays.fill(key, INF);  
        Arrays.fill(parent, -1);  
        key[0] = 0;   
  
        for (int i = 0; i < numVertices - 1; i++) {  
            int minVertex = getMinVertex(mstSet, key);  
            mstSet[minVertex] = true;  
  
            for (int j = 0; j < numVertices; j++) {  
                int edgeWeight = adjacencyMatrix[minVertex][j];  
                if (edgeWeight != INF && !mstSet[j] && edgeWeight < key[j]) {  
                    parent[j] = minVertex;  
                    key[j] = edgeWeight;  
                }  
            }  
        }  
  
        printMST(parent, key);  
    }  
  
    private void printMST(int[] parent, int[] key) {  
        System.out.println("Edge \tWeight");  
        for (int i = 1; i < numVertices; i++)  
            System.out.println(parent[i] + " - " + i + "\t" + key[i]);  
    }  
}

public static void main(String[] args) {  
    Graph graph = new Graph(5);  
    graph.addEdge(0, 1, 2);  
    graph.addEdge(0, 3, 6);  
    graph.addEdge(1, 2, 3);  
    graph.addEdge(1, 3, 8);  
    graph.addEdge(1, 4, 5);  
    graph.addEdge(2, 4, 7);  
    graph.addEdge(3, 4, 9);  
    graph.primMST();  
}

1.3 分支限界法

【基本思想】
分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需的解或活结点表为空时为止。

【解题思路】
找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解.

【实例解析】
优先队列式分支限界法。

import java.util.PriorityQueue;  
  
public class BranchAndBound {  
    // 定义节点类  
    static class Node implements Comparable<Node> {  
        int level; // 节点层数  
        int cost; // 节点代价  
        boolean isLeaf; // 是否为叶子节点  
        Node(int level, int cost, boolean isLeaf) {  
            this.level = level;  
            this.cost = cost;  
            this.isLeaf = isLeaf;  
        }  
        // 根据节点优先级进行比较  
        public int compareTo(Node other) {  
            return Integer.compare(cost, other.cost);  
        }  
    }  
    // 优先队列式分支限界法  
    public static void branchAndBound(Node root) {  
        PriorityQueue<Node> queue = new PriorityQueue<>(); // 创建优先队列  
        queue.offer(root); // 将根节点加入队列中  
        while (!queue.isEmpty()) {  
            Node node = queue.poll(); // 选择优先级最高的节点作为当前扩展节点  
            if (node.isLeaf) {  
                // 如果当前扩展节点是目标节点,则算法结束  
                System.out.println("目标节点找到!");  
                break;  
            } else {  
                // 对当前扩展节点进行扩展,生成所有子节点,并将它们加入优先队列中  
                for (int i = 0; i < 2; i++) {  
                    int level = node.level + 1;  
                    int cost = node.cost + i;  
                    boolean isLeaf = (i == 1); // 假设只有一个叶子节点  
                    Node child = new Node(level, cost, isLeaf);  
                    queue.offer(child); // 将子节点加入队列中  
                }  
            }  
        }  
    }  
    public static void main(String[] args) {  
        int level = 0; // 根节点层数为0  
        int cost = 0; // 根节点代价为0  
        boolean isLeaf = false; // 根节点不是叶子节点  
        Node root = new Node(level, cost, isLeaf); // 创建根节点  
        branchAndBound(root); // 运行分支限界法算法  
    }  
}

三 重点算法总结

3.1 算法的应用场景

算法是解决特定问题或执行特定任务的一组明确的步骤。

  • 排序算法:主要应用在计算机科学中,排序算法用于将一组数据按照特定的顺序(例如升序或降序)排列。
  • 搜索算法:搜索算法用于在数据结构(如数组,链表,树等)中查找特定的元素。这些算法在互联网搜索引擎,数据库系统,文件管理系统等场景中有着广泛的应用。
  • 机器学习算法:从大量数据中提取有用的模式,并做出预测或决策。它们广泛应用于图像和语音识别,推荐系统,预测分析,自动驾驶等领域。
  • 加密算法:在网络安全领域,加密算法用于保护数据的机密性和完整性。这些算法广泛用于电子商务,电子银行,远程办公等场景。
  • 图算法:图算法用于处理图形结构数据,如社交网络、互联网路由、交通网络等。它们在这些复杂网络中寻找路径、检测环路、计算距离等问题。

3.2 如何学习和掌握算法

算法是计算机科学的基础,它们对于解决复杂问题,优化解决方案以及提高程序性能至关重要。

学习算法是一个循序渐进的过程。

  1. 个人可以定期进行算法培训、参加算法挑战项目(在参战过程中获取奖励和认可)。
  2. 机构和企业鼓励员工参加算法竞赛、建立算法基金支持,为那些对算法有深入研究愿望的程序员提供一定的资金支持,这样可以鼓励他们深入研究,发表高质量的研究成果。
  3. 最后,共同推广常用算法以及应用。

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

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

相关文章

Java————栈

一 、栈 Stack继承了Vector&#xff0c;Vector和ArrayList类似&#xff0c;都是动态的顺序表&#xff0c;不同的是Vector是线程安全的。 是一种特殊的线性表&#xff0c; 其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶&#xff0c;另…

《计算机视觉中的多视图几何》笔记(4)

4 Estimation – 2D Projective Transformations 本章主要估计这么几种2D投影矩阵&#xff1a; 2D齐次矩阵&#xff0c;就是从一个图像中的点到另外一个图像中的点的转换&#xff0c;由于点的表示都是齐次的&#xff0c;所以叫齐次矩阵3D到2D的摄像机矩阵基本矩阵三视图之间的…

基于conda的相关命令

conda 查看python版本环境 打开Anaconda Prompt的命令输入框 查看自己的python版本 conda env list激活相应的python版本(环境&#xff09; conda avtivate python_3.9 若输入以下命令可查看python版本 python -V #注意V是大写安装相应的包 pip install 包名5.查看已安装…

智能井盖:提升城市井盖安全管理效率

窨井盖作为城市基础设施的重要组成部分&#xff0c;其安全管理与城市的有序运行和群众的生产生活安全息息相关&#xff0c;体现城市管理和社会治理水平。当前&#xff0c;一些城市已经将智能化的窨井盖升级改造作为新城建的重要内容&#xff0c;推动窨井盖等“城市部件”配套建…

工控机通过Profinet转Modbus RTU网关连接变频器与电机通讯案例

在工业自动化系统中&#xff0c;工控机扮演着重要的角色&#xff0c;它是数据采集、处理和控制的中心。工控机通过Profinet转Modbus RTU网关连接变频器与电机通讯&#xff0c;为工业自动化系统中的设备之间的通信提供了解决方案。工控机通过Profinet转Modbus RTU网关的方式&…

(leetcode)单值二叉树

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 题目&#xff1a; 思路&#xff1a; 代码&#xff1a; 画图与分析&#xff1a; 题目&#xff1a; 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。 只有给定的树是单值二叉树时&…

2023年以就业为目的学习Java还有必要吗?(文末送书)

目录 一、活力四射的 Java二、从零开始学会 Java三、准备工作四、基础知识五、进阶知识六、高级知识七、结语参与方式 大家好&#xff0c;我是哪吒。 文末送5本《Java编程动手学》 今天来探讨一个问题&#xff0c;现在学 Java 找工作还有优势吗&#xff1f; 在某乎上可以看到…

MS1861 视频处理与显示控制器 HDMI转MIPI LVDS转MIPI带旋转功能 图像带缩放,旋转,锐化

1. 基本介绍 MS1861 单颗芯片集成了 HDMI 、 LVDS 和数字视频信号输入&#xff1b;输出端可以驱动 MIPI(DSI-2) 、 LVDS 、 Mini-LVDS 以及 TTL 类型 TFT-LCD 液晶显示。可支持对输入视频信号进行滤波&#xff0c;图 像增强&#xff0c;锐化&#xff0c;对比度调节&am…

ai虚拟主播看车线上虚拟三维展示节约成本和资源

线上车展汽车3D展厅突破了前期虚拟和现实的障碍&#xff0c;使用户无论身在哪个城市&#xff0c;都可以随时随地在线3D看车&#xff0c;极大的方便了消费者的看车的线上体验。因此对企业来说&#xff0c;有购车意愿的顾客必然是会提高成交的可能性&#xff0c;那么如何满足顾客…

固定资产管理系统的特点有哪些

固定资产管理系统是一种用于管理企业固定资产的软件。其功能如下&#xff1a;  自动化管理&#xff1a;固定资产管理系统可自动管理企业固定资产&#xff0c;包括采购、仓储、申请、维护、损坏等流程&#xff0c;大大提高了工作效率。  实时监控&#xff1a;固定资产管理系…

Python 点云处理--半径滤波 【open3d实现】【可视化输出】

目录 一、原理二、环境搭建三、代码实现一、原理 半径滤波以某点为中心画一个圆计算落在该圆中点的数量,当数量大于给定值时,则保留该点,数量小于给定值则剔除该点。因此,使用该算法时需要对搜索半径和近邻点个数阈值进行设置。 二、环境搭建 安装open3d三方库 直接: pi…

准备篇(三)Python 爬虫第三方库

第三方库无法将 "pip" 识别ModuleNotFoundError: No module named pip install 安装路径相关问题requests 库和 BeautifulSoup 库requests 库BeautifulSoup 库第三方库 Python 的 标准库 中提供了许多有用的模块和功能,如字符串处理、网络通信、多线程等,但它们并…

python3.11版本pip install ddddocr调用时报错got an unexpected keyword argument ‘det‘ 解决

一、如图出现如下问题 ddddocr.__init__() got an unexpected keyword argument det出现问题原因&#xff1a;python3.11默认安装版本就旧版的ddddocr1.0的&#xff0c;所以导致如下报错 二、解决方案一&#xff08;推荐&#xff09; python3.11的环境直接安装这个即可&…

我们如何将机器学习应用到 Positive Technologies 产品中

今天&#xff0c;我们将向您介绍 ML 如何帮助安全专家实现自动化操作并检测网络攻击。首先&#xff0c;我们将分析理论基础&#xff0c;然后用我们工作中的案例加以证明。 我们为什么使用 ML 在讨论使用机器学习模型的必要性之前&#xff0c;我们有必要先了解安全工具的工作原…

2023年天津专升本建档立卡、退役免试、大赛获奖免试招生计划

有关普通高校&#xff0c;市大学软件学院&#xff0c;市教育招生考试院&#xff1a; 经有关高校申请&#xff0c;并结合天津实际情况&#xff0c;共安排2023年普通高校高职升本科招生计划3160人&#xff0c;其中安排“建档立卡贫困家庭毕业生专升本专项计划”112人&#xff0c…

【Java 基础篇】Java Properties 详解:配置文件和键值对存储

在 Java 编程中&#xff0c;配置文件和键值对存储是非常常见的需求&#xff0c;用于存储应用程序的配置参数、用户首选项、国际化信息等。Java 提供了 Properties 类来处理这种类型的数据&#xff0c;它是一个轻量级的配置文件和键值对存储工具。本文将详细介绍 Java 的 Proper…

看顶级测工怎么玩转Apifox接口测试工具

一、Apifox简介 官网地址&#xff1a;https://www.apifox.cn/?utm_sourceczzl 1、Apifox 定位 Apifox Postman Swagger Mock JMeterApifox 是 API 文档、API 调试、API Mock、API 自动化测试一体化协作平台。通过一套系统、一份数据&#xff0c;解决多个系统之间的数据同…

嵌入式养成计划-29-网络编程----TCP与UDP的基础模型

Linux下&#xff0c;基于TCP与UDP协议&#xff0c;不同进程下单线程通信服务器 Linux下&#xff0c;基于TCP与UDP协议&#xff0c;不同进程下单线程通信服务器 六十五、TCP与UDP的基础模型 1. socket 1.1 套接字概念 最早的套接字和共享内存&#xff0c;消息队列&#xff…

坚鹏:郴州市银行业协会BLM银行数字化转型战略培训圆满结束

郴州市银行业协会BLM银行数字化转型战略培训圆满结束 在数字化转型背景下&#xff0c;郴州市银行业协会为了落实监管政策《关于银行业保险业数字化转型的指导意见》&#xff0c;充分认识到学习银行银行数字化转型战略的价值和重要性&#xff0c;特别举办《2023年数字化转型战略…

10.4 稳压管稳压电路

虽然整流滤波电路能将正弦交流电压变换成较为平滑的直流电压&#xff0c;但是&#xff0c;一方面&#xff0c;由于输出电压平均值取决于变压器副边电压有效值&#xff0c;所以当电网电压波动时&#xff0c;输出电压平均值将随之产生相应的波动&#xff1b;另一方面&#xff0c;…