【数据结构与算法】《Java 算法宝典:探秘从排序到回溯的奇妙世界》

在这里插入图片描述

目录

  • 标题:《Java 算法宝典:探秘从排序到回溯的奇妙世界》
  • 一、排序算法
    • 1、冒泡排序
    • 2、选择排序
    • 3、插入排序
    • 4、快速排序
    • 5、归并排序
  • 二、查找算法
    • 1、线性查找
    • 2、二分查找
  • 三、递归算法
  • 四、动态规划
  • 五、图算法
    • 1. 深度优先搜索(DFS)
    • 2. 广度优先搜索(BFS)
  • 六、贪心算法
  • 七、分治算法
  • 八、回溯算法

标题:《Java 算法宝典:探秘从排序到回溯的奇妙世界》

摘要: 本文将深入探讨 Java 中的各种基本算法,包括排序、查找、递归、动态规划、图算法、贪心算法、分治算法和回溯算法。通过详细的解释、有趣的例子和可运行的 Java 代码片段,帮助读者轻松掌握这些算法的实现逻辑。无论你是 Java 新手还是经验丰富的开发者,都能从本文中获得宝贵的知识和实用的技巧,提升编程能力。
关键词:Java、算法、排序、查找、递归、动态规划、图算法、贪心算法、分治算法、回溯算法

一、排序算法

1、冒泡排序

  • 原理:重复遍历要排序的数列,比较每对相邻元素的大小,若顺序错误则交换它们的位置。
  • 例子:假设有一组数字 [5, 3, 8, 4, 2],首先比较 5 和 3,交换位置得到 [3, 5, 8, 4, 2],接着比较 5 和 8,不交换,再比较 8 和 4,交换得到 [3, 5, 4, 8, 2],继续比较 8 和 2,交换得到 [3, 5, 4, 2, 8]。这是第一遍遍历的结果,后面继续重复这个过程,直到整个数列有序。
  • Java 代码:
public class BubbleSort {public static void bubbleSort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {// 交换 arr[j] 和 arr[j + 1]int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}
}

2、选择排序

  • 原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后从剩余未排序元素中继续找最小(大)元素,放到已排序序列的末尾。
  • 例子:对于 [5, 3, 8, 4, 2],首先找到最小元素 2,放到第一位得到 [2, 3, 8, 4, 5],然后在剩余元素 [3, 8, 4, 5] 中找到最小元素 3,放到第二位得到 [2, 3, 8, 4, 5],以此类推。
  • Java 代码:
public class SelectionSort {public static void selectionSort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {int minIndex = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}// 交换 arr[i] 和 arr[minIndex]int temp = arr[i];arr[i] = arr[minIndex];arr[minIndex] = temp;}}
}

3、插入排序

  • 原理:构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
  • 例子:以 [5, 3, 8, 4, 2] 为例,首先将 5 视为有序序列,然后处理 3,将 3 插入到 5 前面得到 [3, 5, 8, 4, 2],接着处理 8,保持不变得到 [3, 5, 8, 4, 2],再处理 4,将 4 插入到 3 和 5 之间得到 [3, 4, 5, 8, 2],最后处理 2,将 2 插入到最前面得到 [2, 3, 4, 5, 8]。
  • Java 代码:
public class InsertionSort {public static void insertionSort(int[] arr) {int n = arr.length;for (int i = 1; i < n; i++) {int key = arr[i];int j = i - 1;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j--;}arr[j + 1] = key;}}
}

4、快速排序

  • 原理:通过一个基准值将数据分为两部分,一部分数据比基准值小,另一部分数据比基准值大,然后递归地在这两部分数据上重复这个过程。
  • 例子:对于 [5, 3, 8, 4, 2],选择第一个元素 5 作为基准值,经过一次划分后得到 [3, 4, 2] 和 [8],然后分别对这两部分继续进行快速排序。
  • Java 代码:
public class QuickSort {public static void quickSort(int[] arr, int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}}private static int partition(int[] arr, int low, int high) {int pivot = arr[high];int i = low - 1;for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1;}
}

5、归并排序

  • 原理:采用分治法,将已有序的序列合并成一个新的有序序列。
  • 例子:对于 [5, 3, 8, 4, 2],首先将其分为 [5, 3] 和 [8, 4, 2],然后分别对这两部分进行归并排序,得到 [3, 5] 和 [2, 4, 8],最后将这两个有序序列合并得到 [2, 3, 4, 5, 8]。
  • Java 代码:
public class MergeSort {public static void mergeSort(int[] arr) {if (arr.length > 1) {int mid = arr.length / 2;int[] left = new int[mid];int[] right = new int[arr.length - mid];System.arraycopy(arr, 0, left, 0, mid);System.arraycopy(arr, mid, right, 0, arr.length - mid);mergeSort(left);mergeSort(right);merge(arr, left, right);}}private static void merge(int[] arr, int[] left, int[] right) {int i = 0, j = 0, k = 0;while (i < left.length && j < right.length) {if (left[i] < right[j]) {arr[k++] = left[i++];} else {arr[k++] = right[j++];}}while (i < left.length) {arr[k++] = left[i++];}while (j < right.length) {arr[k++] = right[j++];}}
}

二、查找算法

1、线性查找

  • 原理:从数组的一端开始,逐个检查数组的每个元素,直到找到所需的值。
  • 例子:在 [5, 3, 8, 4, 2] 中查找数字 4,从第一个元素 5 开始,依次比较,直到找到 4。
  • Java 代码:
public class LinearSearch {public static int linearSearch(int[] arr, int target) {for (int i = 0; i < arr.length; i++) {if (arr[i] == target) {return i;}}return -1;}
}

2、二分查找

  • 原理:在有序数组中查找特定元素,通过比较数组中间的元素来确定所需元素是否在数组的哪一半,然后根据比较结果缩小搜索范围,直到找到元素或范围为空。
  • 例子:在 [2, 3, 4, 5, 8] 中查找数字 4,首先比较中间元素 5,发现 4 比 5 小,所以在左边一半继续查找,中间元素是 3,发现 4 比 3 大,所以在右边一半继续查找,中间元素正好是 4,找到目标。
  • Java 代码:
public class BinarySearch {public static int binarySearch(int[] arr, int target) {int low = 0;int high = arr.length - 1;while (low <= high) {int mid = low + (high - low) / 2;if (arr[mid] == target) {return mid;} else if (arr[mid] < target) {low = mid + 1;} else {high = mid - 1;}}return -1;}
}

三、递归算法

原理:递归是一种在问题解决过程中自我调用的算法。它将问题分解为更小的子问题,直到达到基本情况(base case),然后逐步解决这些子问题,最终解决原始问题。
例子:计算阶乘 n!,可以用递归的方式定义为 n! = n * (n - 1)!,当 n = 0 或 1 时,基本情况为 1。
Java 代码:
java
Copy
public class RecursionExample {
public static int factorial(int n) {
if (n == 0 || n == 1) {
return 1;
} else {
return n * factorial(n - 1);
}
}
}

四、动态规划

  • 原理:动态规划是一种将复杂问题分解为更小的子问题,并存储这些子问题的解(通常是在表格中),以避免重复计算的算法。它通常用于求解具有重叠子问题和最优子结构特性的问题。
  • 例子:计算斐波那契数列的第 n 项,可以用动态规划的方法避免重复计算。定义状态 dp [i] 表示斐波那契数列的第 i 项,状态转移方程为 dp [i] = dp [i - 1] + dp [i - 2]。
  • Java 代码:
public class DynamicProgrammingExample {public static int fibonacci(int n) {if (n <= 1) {return n;}int[] dp = new int[n + 1];dp[0] = 0;dp[1] = 1;for (int i = 2; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}
}

标题:《Java 算法奇妙世界:从图算法到回溯,解锁编程新境界》

摘要: 本文将深入探讨 Java 中的基本算法,包括图算法(深度优先搜索 DFS 和广度优先搜索 BFS)、贪心算法、分治算法以及回溯算法。通过详细的解释、有趣的例子和可运行的 Java 代码片段,帮助读者轻松理解这些算法的实现逻辑。无论你是 Java 新手还是经验丰富的开发者,都能从本文中获得宝贵的知识,提升编程技能。快来一起探索 Java 算法的奇妙世界吧!

关键词:Java 算法、图算法、深度优先搜索、广度优先搜索、贪心算法、分治算法、回溯算法

五、图算法

1. 深度优先搜索(DFS)

  • 原理:从图的某个顶点开始,尽可能深地搜索图的顶点,直到达到一个顶点没有未被访问的邻接顶点,然后回溯到上一个顶点继续搜索。
  • 例子:想象你在一个神秘的迷宫中,你的任务是找到出口。你从一个入口开始,沿着一条路径一直走,直到走到死胡同或者已经没有未探索的方向。这时,你就回溯到上一个岔路口,选择另一条路继续探索。这个过程就类似于深度优先搜索。
  • Java 代码:
import java.util.ArrayList;
import java.util.List;class Graph {private int V;private List<List<Integer>> adjList;Graph(int v) {V = v;adjList = new ArrayList<>();for (int i = 0; i < v; i++) {adjList.add(new ArrayList<>());}}void addEdge(int v, int w) {adjList.get(v).add(w);}void DFS(int startVertex) {boolean[] visited = new boolean[V];DFSUtil(startVertex, visited);}private void DFSUtil(int v, boolean[] visited) {visited[v] = true;System.out.print(v + " ");List<Integer> neighbors = adjList.get(v);for (Integer neighbor : neighbors) {if (!visited[neighbor]) {DFSUtil(neighbor, visited);}}}
}

2. 广度优先搜索(BFS)

  • 原理:从图的某个顶点开始,逐层遍历图的顶点,使用队列来记录待访问的顶点。
  • 例子:假设你在一个花园中,要找到一朵特定的花。你从一个起点开始,先检查离起点最近的区域,然后再逐步扩大范围。每次检查完一个区域后,将其周围未检查的区域放入队列中,等待下一轮检查。这个过程就像是广度优先搜索。
  • Java 代码:
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;class Graph {private int V;private List<List<Integer>> adjList;Graph(int v) {V = v;adjList = new ArrayList<>();for (int i = 0; i < v; i++) {adjList.add(new ArrayList<>());}}void addEdge(int v, int w) {adjList.get(v).add(w);}void BFS(int startVertex) {boolean[] visited = new boolean[V];Queue<Integer> queue = new LinkedList<>();visited[startVertex] = true;queue.add(startVertex);while (!queue.isEmpty()) {int currentVertex = queue.poll();System.out.print(currentVertex + " ");List<Integer> neighbors = adjList.get(currentVertex);for (Integer neighbor : neighbors) {if (!visited[neighbor]) {visited[neighbor] = true;queue.add(neighbor);}}}}
}

六、贪心算法

  • 原理:贪心算法是一种在每一步选择中都采取在当前状态下最好或最优的选择,从而希望导致结果是全局最好或最优的算法。
  • 例子:想象你在一个超市购物,你有一个预算,并且想要购买尽可能多的商品。你可以选择价格最低的商品,每次购买一个,直到你的预算用完。这种策略就是贪心算法,虽然不能保证得到全局最优解,但在很多情况下可以得到一个较好的结果。
  • Java 代码:
import java.util.Arrays;
import java.util.Comparator;class Item {int value;int weight;Item(int value, int weight) {this.value = value;this.weight = weight;}
}class GreedyAlgorithmExample {public static double fractionalKnapsack(Item[] items, int capacity) {// 按照价值/重量比进行排序Arrays.sort(items, Comparator.comparingDouble(i -> (double) i.value / i.weight));double totalValue = 0;for (Item item : items) {if (capacity >= item.weight) {totalValue += item.value;capacity -= item.weight;} else {totalValue += (double) capacity / item.weight * item.value;break;}}return totalValue;}
}

七、分治算法

  • 原理:分治算法是一种将问题分解成多个小问题,递归解决小问题,然后合并结果以解决原来的问题的方法。
  • 例子:想象你要计算一个大型图书馆中所有书籍的总页数。你可以将图书馆分成几个区域,分别计算每个区域的书籍总页数,然后将这些结果合并起来得到整个图书馆的总页数。
  • Java 代码:
public class DivideAndConquerExample {public static int sum(int[] arr, int low, int high) {if (low == high) {return arr[low];}int mid = low + (high - low) / 2;int leftSum = sum(arr, low, mid);int rightSum = sum(arr, mid + 1, high);return leftSum + rightSum;}
}

八、回溯算法

  • 原理:回溯算法是一种通过试错的方式尝试分步解决问题的算法。如果某一步不满足要求,它会回退到上一步,尝试另一种可能的选择。
  • 例子:想象你在玩一个数独游戏。你从一个空的格子开始,尝试填入一个数字。如果填入的数字导致矛盾,你就回退到上一个格子,尝试另一个数字。这个过程就是回溯算法。
  • Java 代码:
public class SudokuSolver {public static boolean solveSudoku(char[][] board) {for (int i = 0; i < 9; i++) {for (int j = 0; j < 9; j++) {if (board[i][j] == '.') {for (char k = '1'; k <= '9'; k++) {if (isValid(board, i, j, k)) {board[i][j] = k;if (solveSudoku(board)) {return true;} else {board[i][j] = '.';}}}return false;}}}return true;}private static boolean isValid(char[][] board, int row, int col, char num) {for (int i = 0; i < 9; i++) {if (board[row][i] == num || board[i][col] == num || board[row / 3 * 3 + i / 3][col / 3 * 3 + i % 3] == num) {return false;}}return true;}
}

嘿,小伙伴们!看完了这篇博客,是不是对 Java 中的这些基本算法有了更深入的理解呢?快来评论区分享你在使用这些算法时的经验和心得吧!让我们一起在编程的海洋中畅游,共同进步!😎

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

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

相关文章

transformControls THREE.Object3D.add: object not an instance of THREE.Object3D.

把scene.add(transformControls);改为scene.add(transformControls.getHelper());

计算机视觉专栏(1)【LeNet】论文详解

Lenet 系列 论文精讲部分0.摘要1.引言2.CNN3.结果分析4.总结 论文精讲部分 本专栏旨在深入解析计算机视觉模型的论文及其发展背景&#xff0c;并通过代码部分的实际实验来加深理解。读者可以根据自己的需要参考其中的内容。其主体为原文&#xff0c;笔者理解内容会采用引用格式…

[ 问题解决篇 ] 解决windows虚拟机安装vmtools报错-winserver2012安装vmtools及安装KB2919355补丁 (附离线工具)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

Window on ARM解锁所有的TTS语音包供python调用

Window on ARM解锁所有的TTS语音包供python调用 可用的语音包查看查看TTS可用的语音包解锁语音包设置升级系统打开注册表导出注册表修改注册表导入新的注册表可用的语音包查看 微软的Windows 10操作系统为设备上安装的每种语言提供了一套语音。但只有部分已安装的语音能在整个…

EPLAN创建宏并自定义部件库详细案例操作(三)

#通过导入EDZ格式部件库的样式,模仿制作一个自定义的部件库# 续 EPLAN创建宏并自定义部件库详细案例操作(二) 需要部件库文件(EDZ)格式,可以在此下载: https://download.csdn.net/download/weixin_44166380/89935582 五、创建部件库 本章节的部分操作忽略,具体可参见…

电子电气架构 --- 车载芯片现状

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 所有人的看法和评价都是暂时的&#xff0c;只有自己的经历是伴随一生的&#xff0c;几乎所有的担忧和畏惧…

我docker拉取mysql镜像时用的是latest,我该怎么看我的镜像版本是多少?可以通过一下三种方法查看

我docker拉取mysql镜像时用的是latest&#xff0c;我该怎么看我的镜像版本是多少&#xff1f; 方法一&#xff1a;查看 Docker 镜像标签 你可以查看 Docker 镜像的标签信息&#xff0c;了解当前使用的 MySQL 镜像版本。 具体步骤如下&#xff1a; 1. 列出本地 Docker 镜像&am…

识别风险的提示清单

在PMBOK&#xff08;《项目管理体系指南》&#xff09;中&#xff0c;介绍了这样一个概念&#xff0c;在识别风险时&#xff0c;可以提供一个参考清单&#xff0c;让大家基于一个清单来思考&#xff0c;这个项目可能有哪些具体的风险。 PMBOK中的风险提示清单&#xff0c;包括…

Unreal Engine 5 C++(C#)开发:使用蓝图库实现插件(二)编辑BPLibrary.h中的枚举及结构体

目录 引言 一、头文件编写 1.1Kismet/BlueprintFunctionLibrary.h 1.2BPLibrary.generated.h的作用 1.3IImageWrapper.h 1.4 IImageWrapperModule.h 1.5 Engine/Texture2D.h 1.6CoreMinimal.h 二、定义图片/路径类型的枚举 2.1图片枚举类EImageType 2.2路径枚举类EPath…

Vuestic 整理使用

简单示例 1. 条件渲染 2. 列表渲染 3. 组件插槽 4. 插值语法 5. 前后端路由的区别(还是转一下,可以减少代码量)SFC 构建 … … Okay&#xff0c;可以干活了&#xff0c;通顺 数据表的操作更加简化了 数据类别通过后端路由区别,但是还得由前端路由转一下 简单了许多呀,上脚手…

ssm017网上花店设计+vue(论文+源码)_kaic

设计题目&#xff1a;网上花店的设计与实现 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信…

网页上视频没有提供下载权限怎么办?

以腾讯会议录屏没有提供下载权限为例&#xff0c;该怎么办呢&#xff1f; 最好的办法就是找到管理员&#xff0c;开启下载权限。如果找不到呢&#xff0c;那就用这个办法下载。 1.打开Microsoft Edge浏览器的扩展 2.搜索“视频下载”&#xff0c;选择“视频下载Pro” 3.点击“…

使用pyecharts绘制词云图

一、什么是词云图&#xff1f; 词云图是一种用来展现高频关键词的可视化表达&#xff0c;通过文字、色彩、图形的搭配&#xff0c;产生有冲击力地视觉效果&#xff0c;而且能够传达有价值的信息。 制作词云图的网站有很多&#xff0c;简单方便&#xff0c;适合小批量操作。 …

一、ARMv8寄存器之通用、状态、特殊寄存器

ARMV8核心寄存器数量是非常大的&#xff0c;为了更好的学习&#xff0c;可以划分为以下几大类&#xff1a; 通用寄存器。这类寄存器主要是用来暂存数据和参与运算。通过load\store指令操作。状态寄存器。AArch64体系结构使用PSTATE寄存器表示当前处理器状态。特殊寄存器。有专门…

云渲染突破酒店3D动画渲染速度与成本瓶颈!

3D动画已经成为众多行业&#xff0c;尤其是酒店业&#xff0c;用于营销和展示其独特卖点的重要工具。通过生动的3D动画&#xff0c;酒店能够突出其特色和优势&#xff0c;从而吸引更多潜在客户。然而&#xff0c;在3D动画制作过程中&#xff0c;渲染环节往往是一个耗时且技术要…

LabVIEW偏振调制激光高精度测距系统

在航空航天、汽车制造、桥梁建筑等先进制造领域&#xff0c;许多大型零件的装配精度要求越来越高&#xff0c;传统的测距方法在面对大尺寸、高精度测量时&#xff0c;难以满足工业应用的要求。绝对测距技术在大尺度测量上往往会因受环境影响大、测距精度低而无法满足需求。基于…

WPF+MVVM案例实战(六)- 自定义分页控件实现

文章目录 1、项目准备2、功能实现1、分页控件 DataPager 实现2、分页控件数据模型与查询行为3、数据界面实现 3、运行效果4、源代码获取 1、项目准备 打开项目 Wpf_Examples&#xff0c;新建 PageBarWindow.xaml 界面、PageBarViewModel.cs ,在用户控件库 UserControlLib中创建…

WPF+MVVM案例实战(十一)- 环形进度条实现

文章目录 1、运行效果2、功能实现1、文件创建与代码实现2、角度转换器实现3、命名空间引用3、源代码下载1、运行效果 2、功能实现 1、文件创建与代码实现 打开 Wpf_Examples 项目,在Views 文件夹下创建 CircularProgressBar.xaml 窗体文件。 CircularProgressBar.xaml 代码实…

系统架构图设计(行业领域架构)

物联网 感知层&#xff1a;主要功能是感知和收集信息。感知层通过各种传感器、RFID标签等设备来识别物体、采集信息&#xff0c;并对这些信息进行初步处理。这一层的作用是实现对物理世界的感知和初步处理&#xff0c;为上层提供数据基础网络层&#xff1a;网络层负责处理和传输…

sublime Text中设置编码为GBK

要在sublime Text中设置编码为GBK&#xff0c;请按照以下步骤操作 1.打开Sublime Text编辑器, 2.点击菜单栏中的“Preferences”(首选项)选项&#xff0c;找打Package Control选项。 3.点击Package Control&#xff0c;随后搜索Install Package并点击&#xff0c;如下图 4.再…