• 面试系列 - Java常见算法(一)


    目录

    一、排序算法

    1、冒泡排序(Bubble Sort):

    2、快速排序(Quick Sort):

    二、查找算法

    1、二分查找(Binary Search):

    三、 图算法

    1、深度优先搜索(Depth-First Search,DFS): 

     2、广度优先搜索(Breadth-First Search,BFS):


    一、排序算法

    1、冒泡排序(Bubble Sort):

    冒泡排序(Bubble Sort)是一种简单的排序算法,它多次遍历要排序的元素列表,每次比较相邻的两个元素,并交换它们,如果它们的顺序不正确。这个过程重复进行,直到整个列表排好序为止。

    1. public class BubbleSort {
    2. public static void main(String[] args) {
    3. int[] arr = {64, 34, 25, 12, 22, 11, 90};
    4. System.out.println("排序前的数组:");
    5. printArray(arr);
    6. bubbleSort(arr);
    7. System.out.println("\n排序后的数组:");
    8. printArray(arr);
    9. }
    10. public static void bubbleSort(int[] arr) {
    11. int n = arr.length;
    12. boolean swapped;
    13. for (int i = 0; i < n - 1; i++) {
    14. swapped = false;
    15. for (int j = 0; j < n - i - 1; j++) {
    16. if (arr[j] > arr[j + 1]) {
    17. // 交换 arr[j] 和 arr[j+1] 的位置
    18. int temp = arr[j];
    19. arr[j] = arr[j + 1];
    20. arr[j + 1] = temp;
    21. swapped = true;
    22. }
    23. }
    24. // 如果在一轮中没有发生交换,说明列表已经排序完成,可以提前退出
    25. if (!swapped) {
    26. break;
    27. }
    28. }
    29. }
    30. public static void printArray(int[] arr) {
    31. int n = arr.length;
    32. for (int i = 0; i < n; i++) {
    33. System.out.print(arr[i] + " ");
    34. }
    35. System.out.println();
    36. }
    37. }

    在这个示例中,bubbleSort 函数对给定的整数数组进行冒泡排序,printArray 函数用于打印数组的内容。冒泡排序的核心是嵌套的循环,外循环控制每次遍历的范围,内循环用于比较相邻元素并进行交换。

    冒泡排序的时间复杂度是 O(n^2),在大规模数据集上性能较差,但对于小规模数据集或基本有序的数据集,它可能是一个简单且容易实现的排序方法。

    2、快速排序(Quick Sort):

    快速排序(Quick Sort)是一种高效的排序算法,它采用分治策略来将一个数组分为两个子数组,然后递归地对子数组进行排序。

    1. public class QuickSort {
    2. public static void main(String[] args) {
    3. int[] arr = {64, 34, 25, 12, 22, 11, 90};
    4. System.out.println("排序前的数组:");
    5. printArray(arr);
    6. quickSort(arr, 0, arr.length - 1);
    7. System.out.println("\n排序后的数组:");
    8. printArray(arr);
    9. }
    10. public static void quickSort(int[] arr, int low, int high) {
    11. if (low < high) {
    12. int pivotIndex = partition(arr, low, high);
    13. quickSort(arr, low, pivotIndex - 1);
    14. quickSort(arr, pivotIndex + 1, high);
    15. }
    16. }
    17. public static int partition(int[] arr, int low, int high) {
    18. int pivot = arr[high];
    19. int i = low - 1;
    20. for (int j = low; j < high; j++) {
    21. if (arr[j] < pivot) {
    22. i++;
    23. // 交换 arr[i] 和 arr[j] 的位置
    24. int temp = arr[i];
    25. arr[i] = arr[j];
    26. arr[j] = temp;
    27. }
    28. }
    29. // 交换 arr[i+1] 和 arr[high] 的位置,将pivot放在正确的位置
    30. int temp = arr[i + 1];
    31. arr[i + 1] = arr[high];
    32. arr[high] = temp;
    33. return i + 1;
    34. }
    35. public static void printArray(int[] arr) {
    36. int n = arr.length;
    37. for (int i = 0; i < n; i++) {
    38. System.out.print(arr[i] + " ");
    39. }
    40. System.out.println();
    41. }
    42. }

    这个示例中,quickSort 函数对给定的整数数组进行快速排序,partition 函数用于选择一个元素作为主元(通常选择最后一个元素),并将小于主元的元素移到主元的左侧,大于主元的元素移到主元的右侧。

    快速排序的时间复杂度通常为 O(n log n),在平均情况下表现良好,但在最坏情况下可能为 O(n^2),这取决于主元的选择。然而,通过选择随机的主元或使用三数中值法等优化策略,可以降低最坏情况的概率。

    二、查找算法

    1、二分查找(Binary Search):

    二分查找(Binary Search)是一种高效的搜索算法,用于在有序数组中查找特定的元素。以下是Java中的二分查找算法示例:

    1. public class BinarySearch {
    2. public static void main(String[] args) {
    3. int[] arr = {11, 12, 22, 25, 34, 64, 90};
    4. int target = 25;
    5. int result = binarySearch(arr, target);
    6. if (result == -1) {
    7. System.out.println("未找到目标元素 " + target);
    8. } else {
    9. System.out.println("目标元素 " + target + " 位于索引 " + result);
    10. }
    11. }
    12. public static int binarySearch(int[] arr, int target) {
    13. int left = 0, right = arr.length - 1;
    14. while (left <= right) {
    15. int mid = left + (right - left) / 2;
    16. if (arr[mid] == target) {
    17. return mid; // 找到目标元素,返回索引
    18. } else if (arr[mid] < target) {
    19. left = mid + 1; // 在右半部分继续查找
    20. } else {
    21. right = mid - 1; // 在左半部分继续查找
    22. }
    23. }
    24. return -1; // 未找到目标元素
    25. }
    26. }

    在这个示例中,binarySearch 函数接受一个有序数组和一个目标元素作为输入,并返回目标元素的索引,如果未找到目标元素,则返回 -1。算法的核心思想是在每次迭代中,将目标元素与数组的中间元素进行比较,然后根据比较结果缩小搜索范围。

    二分查找的时间复杂度是 O(log n),其中 n 是数组的长度。这使它成为在大型有序数据集上查找元素的一种非常高效的方法。但要注意,二分查找要求数组必须是有序的。

    三、 图算法

    1、深度优先搜索(Depth-First Search,DFS): 

    深度优先搜索(Depth-First Search,DFS)是一种用于遍历或搜索图形和树数据结构的算法。DFS的基本思想是从起始节点开始,沿着一条路径尽可能深入,直到无法前进为止,然后回溯并继续搜索其他路径

    1. import java.util.*;
    2. class Graph {
    3. private int V; // 图的顶点数
    4. private LinkedList adj[]; // 邻接列表
    5. Graph(int v) {
    6. V = v;
    7. adj = new LinkedList[v];
    8. for (int i = 0; i < v; ++i)
    9. adj[i] = new LinkedList();
    10. }
    11. // 添加边
    12. void addEdge(int v, int w) {
    13. adj[v].add(w);
    14. }
    15. // 从顶点s开始进行DFS遍历
    16. void DFS(int s) {
    17. boolean visited[] = new boolean[V];
    18. DFSUtil(s, visited);
    19. }
    20. // 辅助函数用于递归遍历
    21. void DFSUtil(int v, boolean visited[]) {
    22. visited[v] = true;
    23. System.out.print(v + " ");
    24. Iterator i = adj[v].listIterator();
    25. while (i.hasNext()) {
    26. int n = i.next();
    27. if (!visited[n])
    28. DFSUtil(n, visited);
    29. }
    30. }
    31. }
    32. public class DFSExample {
    33. public static void main(String[] args) {
    34. Graph g = new Graph(7);
    35. g.addEdge(0, 1);
    36. g.addEdge(0, 2);
    37. g.addEdge(1, 3);
    38. g.addEdge(1, 4);
    39. g.addEdge(2, 5);
    40. g.addEdge(2, 6);
    41. System.out.println("DFS遍历结果:");
    42. g.DFS(0);
    43. }
    44. }

    在这个示例中,我们创建了一个有7个节点的图,然后使用深度优先搜索(DFS)从节点0开始遍历图。Graph 类包含了图的表示,DFS 方法用于启动遍历,DFSUtil 方法是递归的辅助函数,它用于深入遍历图中的节点。

    DFS在树结构和图形遍历中非常有用,并且可以用于解决许多问题,例如查找路径、拓扑排序、连通性检查等。DFS的时间复杂度是O(V + E),其中V是顶点数,E是边数。

     2、广度优先搜索(Breadth-First Search,BFS):

    广度优先搜索(Breadth-First Search,BFS)是一种用于遍历或搜索图形和树数据结构的算法。BFS从起始节点开始,首先访问该节点,然后逐层访问与该节点直接相邻的节点,然后再依次访问这些相邻节点的相邻节点,以此类推。

    1. import java.util.*;
    2. class Graph {
    3. private int V; // 图的顶点数
    4. private LinkedList adj[]; // 邻接列表
    5. Graph(int v) {
    6. V = v;
    7. adj = new LinkedList[v];
    8. for (int i = 0; i < v; ++i)
    9. adj[i] = new LinkedList();
    10. }
    11. // 添加边
    12. void addEdge(int v, int w) {
    13. adj[v].add(w);
    14. }
    15. // 从顶点s开始进行BFS遍历
    16. void BFS(int s) {
    17. boolean visited[] = new boolean[V];
    18. LinkedList queue = new LinkedList();
    19. visited[s] = true;
    20. queue.add(s);
    21. while (queue.size() != 0) {
    22. s = queue.poll();
    23. System.out.print(s + " ");
    24. Iterator i = adj[s].listIterator();
    25. while (i.hasNext()) {
    26. int n = i.next();
    27. if (!visited[n]) {
    28. visited[n] = true;
    29. queue.add(n);
    30. }
    31. }
    32. }
    33. }
    34. }
    35. public class BFSExample {
    36. public static void main(String[] args) {
    37. Graph g = new Graph(7);
    38. g.addEdge(0, 1);
    39. g.addEdge(0, 2);
    40. g.addEdge(1, 3);
    41. g.addEdge(1, 4);
    42. g.addEdge(2, 5);
    43. g.addEdge(2, 6);
    44. System.out.println("BFS遍历结果:");
    45. g.BFS(0);
    46. }
    47. }

    在这个示例中,我们创建了一个有7个节点的图,然后使用广度优先搜索(BFS)从节点0开始遍历图。Graph 类包含了图的表示,BFS 方法用于启动遍历,它使用队列来管理要访问的节点。在BFS中,节点按照层级的顺序被访问,这使得它非常适合查找最短路径等问题。

    BFS在图形遍历、路径查找和连通性检查等问题中非常有用。它的时间复杂度是O(V + E),其中V是顶点数,E是边数。BFS通常使用队列来实现,确保先访问的节点先被处理,从而实现层级遍历的效果。

  • 相关阅读:
    jquery监听滚动条,实现“返回顶部”
    【测试开发】用例篇 · 熟悉黑盒测试用例设计方法(1)等价类划分法、边界值法、判定表法
    使用神经网络进行预测,图神经网络 社交网络
    E-梅莉的市场经济学
    Windows版 PostgreSQL 利用 pg_upgrade 进行大版升级操作
    在 vue-cli 构建的项目中配置使用资源CDN,加速我们的项目
    项目整合管理
    EMT4J——让 Java 应用升级更轻松
    使用Microsoft.SemanticKernel基于本地运行的Ollama大语言模型实现Agent调用函数
    javaweb(三)
  • 原文地址:https://blog.csdn.net/TreeShu321/article/details/133298256