【数据结构与算法】《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.rhkb.cn/news/458322.html

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

相关文章

Ubuntu22.04环境搭建MQTT服务器

官网&#xff1a; https://mosquitto.org 1.引入库 sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa2.升级安装工具 sudo apt-get update 3.安装 sudo apt-get install mosquitto 4.安装客户端 sudo apt-get install mosquitto-clients5.添加修改配置文件 进…

MySql数据库中数据类型

本篇将介绍在 MySql 中的所有数据类型&#xff0c;其中主要分为四类&#xff1a;数值类型、文本和二进制类型、时间日期、String 类型。如下&#xff08;图片来源&#xff1a;MySQL数据库&#xff09;&#xff1a; 目录如下&#xff1a; 目录 数值类型 1. 整数类型 2. …

Python | Leetcode Python题解之第516题最长回文子序列

题目&#xff1a; 题解&#xff1a; class Solution:def longestPalindromeSubseq(self, s: str) -> int:n len(s)dp [[0] * n for _ in range(n)]for i in range(n - 1, -1, -1):dp[i][i] 1for j in range(i 1, n):if s[i] s[j]:dp[i][j] dp[i 1][j - 1] 2else:dp…

【java】java的基本程序设计结构04-数值类型的转换

类型默认值 int, short, long, byte 的默认值是0。char 的默认值是 \u0000&#xff08;空字符&#xff09;。float 的默认值是 0.0f。double 的默认值是 0.0d。boolean 的默认值是 false。引用类型&#xff08;类、接口、数组&#xff09;的默认值是 null。 引用类型 在Java中…

Kafka如何控制消费的位置?

大家好&#xff0c;我是锋哥。今天分享关于【Kafka如何控制消费的位置?】面试题&#xff1f;希望对大家有帮助&#xff1b; Kafka如何控制消费的位置? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Kafka 中&#xff0c;控制消费位置主要通过以下几个机制来实…

C++-继承

目录 一、继承的概念和定义 1、继承概念 2、继承的语法格式 3、继承的方式 4、继承类模板 二、基类和派生类之间的转换 三、继承中的作用域 四、派生类的默认成员函数 一、默认成员函数介绍 1、派生类中基类成员的构造 2、派生类中基类成员拷贝构造 3、复制重载 4、…

帝佛卡干邑荣耀登陆泰国王权King Power

帝佛卡干邑与泰国王权免税集团&#xff08;King Power&#xff09;达成深度合作&#xff0c;共同将法国帝佛卡干邑品牌推向泰国旅游零售市场。此次合作不仅标志着帝佛卡干邑在国际市场的又一重要突破&#xff0c;也彰显了双方对高品质产品的共同追求。 帝佛卡干邑于2024年8月正…

[Python学习日记-53] Python 中的正则表达式模块 —— re

[Python学习日记-53] Python 中的正则表达式模块 —— re 简介 re 模块 练习 简介 我们在编程的时候经常会遇到想在一段文字当中找出电话号码、身份证号、身高、年龄之类的信息&#xff0c;就像下面的数据一样 # 文件名&#xff1a;美丽学姐联系方式.txt 姓名 地区 …

WinRAR技巧:如何独立压缩文件夹内的每个文件?

不知道大家是否会遇到这种情况&#xff0c;将文件夹内的多个文件或文件夹压缩成一个个压缩包文件&#xff0c;这种情况除了将文件夹中的文件一个个压缩&#xff0c;还有什么批量操作的方法呢&#xff1f;今天分享使用WinRAR批量压缩文件到每个单独的文件夹的方法。 方法如下&a…

pdf压缩如何操作?教你8招,轻松搞定文件压缩!

电脑上如果存有大量的pdf文件&#xff0c;那么一定会占用一定的空间&#xff0c;不仅不利于存储还影响传输速度。如果想要将pdf压缩变小&#xff0c;那么本文分享的内容可就要了解下了。 PDF文件怎么压缩变小&#xff1f;pdf压缩是一种常见的文件处理需求。无论是处理个人文档…

offset Explorer连接云服务上的kafka连接不上

以上配置后报连接错误时&#xff0c;可能是因为kafka的server.properties配置文件没配置好&#xff1a; 加上面两条配置&#xff0c;再次测试连接&#xff0c;成功 listeners和advertised.listeners

DICOM 基础知识:深入理解DICOM数据结构与标签说明

目录 DICOM 图像概念 DICOM 图像关键特性&#xff1a; DICOM 文件结构 常见数据元素&#xff1a; 数据元素示例详解 DICOM-VR 数据类型说明 DICOM 标准支持的数据集 结语 DICOM 图像概念 DICOM&#xff08;Digital Imaging and Communications in Medicine&…

ELK之路第二步——可视化界面Kibana

Kibana 1.安装2.解压3.修改配置4.启动 这部分内容就比较简单了&#xff0c;水一片文章。 1.安装 需要梯子 官网下载链接&#xff1a;https://www.elastic.co/cn/downloads/past-releases/kibana-7-3-0 如果你去官网下载页面&#xff0c;点击下载是404报错&#xff0c;记得切换…

UE5之5.4 第三人称示例代码阅读

第三人称的代码相对第一人称少了很多&#xff0c;只有一个移动跳跃的能力 构造函数&#xff0c;添加角色的移动属性&#xff0c;限制了当controller移动角色不会乱转&#xff0c;然后创建了一个相机杆&#xff0c;创建了一个跟随相机&#xff0c;绑到相机杆上 然后在这个函数设…

SpringMVC6-SpringMVC的视图

目录 ThymeleafView 转发视图 重定向视图 视图控制器view-controller SpringMVC中的视图是View接口&#xff0c;视图的作用&#xff1a;渲染数据&#xff0c;将模型Model中的数据展示给用户 SpringMVC视图的种类很多&#xff0c;默认有转发视图InternalResourceView 和重定…

基于Qt的多线程并行和循序运行实验Demo

致谢&#xff08;Acknowledgement&#xff09;&#xff1a; 感谢Youtube博主Qt With Ketan与KDAB精心录制的Qt多线程处理应用教程&#xff0c;感谢Bilibili博主爱编程的大丙对Qt多线程与线程池内容深入浅出的讲解。 一、计算机线程相关概念 线程概念[1]&#xff1a; 在计算机科…

【Anaconda】Anaconda3 下载与安装教程(Windows 11)

引言 Anaconda发行版是一个用于数据科学、机器学习和AI项目的平台。它包括数千个开源包&#xff0c;一个包和环境管理器&#xff0c;一个桌面应用程序&#xff0c;以及云服务。 安装步骤 下载安装程序 访问官方Anaconda网站下载安装程序。 https://www.anaconda.com/download/…

关闭windows更新方法

在windows更新里选择暂停windows更新 然后按下winr&#xff0c;输入regedit 在注册表里找到 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings\PauseUpdatesExpiryTime 修改时间即可

联想笔记本电脑睡眠后打开黑屏解决方法

下载联想机器睡眠无法唤醒修复工具 下载地址&#xff1a;https://tools.lenovo.com.cn/exeTools/detail/id/233/rid/6182522.html 使用完后重启电脑&#xff0c;问题解决。

多线程进阶——线程池的实现

什么是池化技术 池化技术是一种资源管理策略&#xff0c;它通过重复利用已存在的资源来减少资源的消耗&#xff0c;从而提高系统的性能和效率。在计算机编程中&#xff0c;池化技术通常用于管理线程、连接、数据库连接等资源。 我们会将可能使用的资源预先创建好&#xff0c;…