Java 是一种功能强大且广泛使用的编程语言,适合实现各种算法。以下是一些 Java 中常用的算法,按类别整理,并附有简要说明和代码示例。
目录
1. 排序算法
冒泡排序
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 - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
快速排序
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 - 1; 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;
}
}
归并排序
public class MergeSort {
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
}
private static void merge(int[] arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
int[] L = new int[n1];
int[] R = new int[n2];
for (int i = 0; i < n1; ++i) {
L[i] = arr[left + i];
}
for (int j = 0; j < n2; ++j) {
R[j] = arr[mid + 1 + j];
}
int i = 0, j = 0;
int k = left;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
}
2. 搜索算法
二分搜索
public class BinarySearch {
public static int binarySearch(int[] arr, int x) {
int left = 0, right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == x) {
return mid;
}
if (arr[mid] < x) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
}
深度优先搜索 (DFS)
import java.util.*;
public class DFS {
public static void dfs(int v, boolean[] visited, List<List<Integer>> adjList) {
visited[v] = true;
System.out.print(v + " ");
for (int u : adjList.get(v)) {
if (!visited[u]) {
dfs(u, visited, adjList);
}
}
}
public static void main(String[] args) {
int vertices = 4;
List<List<Integer>> adjList = new ArrayList<>();
for (int i = 0; i < vertices; i++) {
adjList.add(new ArrayList<>());
}
adjList.get(0).add(1);
adjList.get(0).add(2);
adjList.get(1).add(2);
adjList.get(2).add(0);
adjList.get(2).add(3);
adjList.get(3).add(3);
boolean[] visited = new boolean[vertices];
System.out.println("DFS starting from vertex 2:");
dfs(2, visited, adjList);
}
}
广度优先搜索 (BFS)
import java.util.*;
public class BFS {
public static void bfs(int s, int vertices, List<List<Integer>> adjList) {
boolean[] visited = new boolean[vertices];
LinkedList<Integer> queue = new LinkedList<>();
visited[s] = true;
queue.add(s);
while (queue.size() != 0) {
s = queue.poll();
System.out.print(s + " ");
for (int n : adjList.get(s)) {
if (!visited[n]) {
visited[n] = true;
queue.add(n);
}
}
}
}
public static void main(String[] args) {
int vertices = 4;
List<List<Integer>> adjList = new ArrayList<>();
for (int i = 0; i < vertices; i++) {
adjList.add(new ArrayList<>());
}
adjList.get(0).add(1);
adjList.get(0).add(2);
adjList.get(1).add(2);
adjList.get(2).add(0);
adjList.get(2).add(3);
adjList.get(3).add(3);
System.out.println("BFS starting from vertex 2:");
bfs(2, vertices, adjList);
}
}
3. 动态规划
斐波那契数列
public class FibonacciDP {
public static int fibonacci(int n) {
if (n <= 1) {
return n;
}
int[] fib = new int[n + 1];
fib[0] = 0;
fib[1] = 1;
for (int i = 2; i <= n; i++) {
fib[i] = fib[i - 1] + fib[i - 2];
}
return fib[n];
}
}
最长公共子序列 (LCS)
public class LongestCommonSubsequence {
public static int lcs(String s1, String s2) {
int m = s1.length();
int t = s2.length();
int[][] dp = new int[m + 1][t + 1];
for (int i = 0; i <= m; i++) {
for (int j = 0; j <= t; j++) {
if (i == 0 || j == 0) {
dp[i][j] = 0;
} else if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[m][t];
}
}
4. 贪心算法
活动选择问题
import java.util.*;
public class ActivitySelection {
public static void activitySelection(int[] start, int[] finish) {
int n = start.length;
List<Integer> selectedActivities = new ArrayList<>();
selectedActivities.add(0);
int lastSelected = 0;
for (int i = 1; i < n; i++) {
if (start[i] >= finish[lastSelected]) {
selectedActivities.add(i);
lastSelected = i;
}
}
System.out.println("Selected activities: " + selectedActivities);
}
public static void main(String[] args) {
int[] start = {1, 3, 0, 5, 8, 5};
int[] finish = {2, 4, 6, 7, 9, 9};
activitySelection(start, finish);
}
}
分数背包问题
import java.util.*;
class Item {
int value, weight;
public Item(int value, int weight) {
this.value = value;
this.weight = weight;
}
}
public class FractionalKnapsack {
public static double fractionalKnapsack(int W, Item[] arr) {
Arrays.sort(arr, (a, b) -> Double.compare((double) b.value / b.weight, (double) a.value / a.weight));
double totalValue = 0.0;
for (Item item : arr) {
if (W == 0) {
break;
}
if (item.weight <= W) {
W -= item.weight;
totalValue += item.value;
} else {
totalValue += (double) item.value * W / item.weight;
W = 0;
}
}
return totalValue;
}
public static void main(String[] args) {
int W = 50;
Item[] arr = {new Item(60, 10), new Item(100, 20), new Item(120, 30)};
System.out.println("Maximum value in Knapsack = " + fractionalKnapsack(W, arr));
}
}
5. 图算法
Dijkstra 算法
import java.util.*;
public class Dijkstra {
static class Node implements Comparable<Node> {
int vertex, weight;
public Node(int vertex, int weight) {
this.vertex = vertex;
this.weight = weight;
}
@Override
public int compareTo(Node other) {
return Integer.compare(this.weight, other.weight);
}
}
public static void dijkstra(List<List<Node>> graph, int src) {
int V = graph.size();
int[] dist = new int[V];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[src] = 0;
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.add(new Node(src, 0));
while (!pq.isEmpty()) {
Node node = pq.poll();
int u = node.vertex;
for (Node neighbor : graph.get(u)) {
int v = neighbor.vertex;
int weight = neighbor.weight;
if (dist[u] + weight < dist[v]) {
dist[v] = dist[u] + weight;
pq.add(new Node(v, dist[v]));
}
}
}
System.out.println("Vertex Distance from Source");
for (int i = 0; i < V; i++) {
System.out.println(i + " \t\t " + dist[i]);
}
}
public static void main(String[] args) {
int V = 5;
List<List<Node>> graph = new ArrayList<>();
for (int i = 0; i < V; i++) {
graph.add(new ArrayList<>());
}
graph.get(0).add(new Node(1, 9));
graph.get(0).add(new Node(2, 6));
graph.get(0).add(new Node(3, 5));
graph.get(0).add(new Node(4, 3));
graph.get(2).add(new Node(1, 2));
graph.get(2).add(new Node(3, 4));
dijkstra(graph, 0);
}
}
Prim 算法
import java.util.*;
public class Prim {
static class Node implements Comparable<Node> {
int vertex, key;
public Node(int vertex, int key) {
this.vertex = vertex;
this.key = key;
}
@Override
public int compareTo(Node other) {
return Integer.compare(this.key, other.key);
}
}
public static void primMST(List<List<Node>> graph) {
int V = graph.size();
boolean[] inMST = new boolean[V];
int[] key = new int[V];
int[] parent = new int[V];
Arrays.fill(key, Integer.MAX_VALUE);
Arrays.fill(parent, -1);
PriorityQueue<Node> pq = new PriorityQueue<>();
key[0] = 0;
pq.add(new Node(0, key[0]));
while (!pq.isEmpty()) {
int u = pq.poll().vertex;
inMST[u] = true;
for (Node neighbor : graph.get(u)) {
int v = neighbor.vertex;
int weight = neighbor.key;
if (!inMST[v] && weight < key[v]) {
key[v] = weight;
pq.add(new Node(v, key[v]));
parent[v] = u;
}
}
}
for (int i = 1; i < V; i++) {
System.out.println("Edge: " + parent[i] + " - " + i + " weight: " + key[i]);
}
}
public static void main(String[] args) {
int V = 5;
List<List<Node>> graph = new ArrayList<>();
for (int i = 0; i < V; i++) {
graph.add(new ArrayList<>());
}
graph.get(0).add(new Node(1, 2));
graph.get(0).add(new Node(3, 6));
graph.get(1).add(new Node(0, 2));
graph.get(1).add(new Node(2, 3));
graph.get(1).add(new Node(3, 8));
graph.get(1).add(new Node(4, 5));
graph.get(2).add(new Node(1, 3));
graph.get(2).add(new Node(4, 7));
graph.get(3).add(new Node(0, 6));
graph.get(3).add(new Node(1, 8));
graph.get(4).add(new Node(1, 5));
graph.get(4).add(new Node(2, 7));
primMST(graph);
}
}
6. 树算法
二叉树的遍历
public class BinaryTreeTraversal {
static class Node {
int data;
Node left, right;
public Node(int data) {
this.data = data;
left = right = null;
}
}
Node root;
public void inorderTraversal(Node node) {
if (node != null) {
inorderTraversal(node.left);
System.out.print(node.data + " ");
inorderTraversal(node.right);
}
}
public void preorderTraversal(Node node) {
if (node != null) {
System.out.print(node.data + " ");
preorderTraversal(node.left);
preorderTraversal(node.right);
}
}
public void postorderTraversal(Node node) {
if (node != null) {
postorderTraversal(node.left);
postorderTraversal(node.right);
System.out.print(node.data + " ");
}
}
public static void main(String[] args) {
BinaryTreeTraversal tree = new BinaryTreeTraversal();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
System.out.println("Inorder traversal:");
tree.inorderTraversal(tree.root);
System.out.println("\nPreorder traversal:");
tree.preorderTraversal(tree.root);
System.out.println("\nPostorder traversal:");
tree.postorderTraversal(tree.root);
}
}
二叉搜索树 (BST) 插入
public class BinarySearchTree {
static class Node {
int key;
Node left, right;
public Node(int item) {
key = item;
left = right = null;
}
}
Node root;
BinarySearchTree() {
root = null;
}
void insert(int key) {
root = insertRec(root, key);
}
Node insertRec(Node root, int key) {
if (root == null) {
root = new Node(key);
return root;
}
if (key < root.key) {
root.left = insertRec(root.left, key);
} else if (key > root.key) {
root.right = insertRec(root.right, key);
}
return root;
}
void inorder() {
inorderRec(root);
}
void inorderRec(Node root) {
if (root != null) {
inorderRec(root.left);
System.out.print(root.key + " ");
inorderRec(root.right);
}
}
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
tree.insert(50);
tree.insert(30);
tree.insert(20);
tree.insert(40);
tree.insert(70);
tree.insert(60);
tree.insert(80);
System.out.println("Inorder traversal:");
tree.inorder();
}
}
7. 字符串处理算法
KMP 字符串匹配算法
public class KMP {
void KMPSearch(String pat, String txt) {
int M = pat.length();
int N = txt.length();
int[] lps = new int[M];
int j = 0;
computeLPSArray(pat, M, lps);
int i = 0;
while (i < N) {
if (pat.charAt(j) == txt.charAt(i)) {
j++;
i++;
}
if (j
== M) {
System.out.println("Found pattern at index " + (i - j));
j = lps[j - 1];
} else if (i < N && pat.charAt(j) != txt.charAt(i)) {
if (j != 0) {
j = lps[j - 1];
} else {
i++;
}
}
}
}
void computeLPSArray(String pat, int M, int[] lps) {
int len = 0;
lps[0] = 0;
int i = 1;
while (i < M) {
if (pat.charAt(i) == pat.charAt(len)) {
len++;
lps[i] = len;
i++;
} else {
if (len != 0) {
len = lps[len - 1];
} else {
lps[i] = len;
i++;
}
}
}
}
public static void main(String[] args) {
String txt = "ABABDABACDABABCABAB";
String pat = "ABABCABAB";
new KMP().KMPSearch(pat, txt);
}
}
Rabin-Karp 算法
public class RabinKarp {
public final static int d = 256;
public final static int q = 101;
static void search(String pat, String txt) {
int M = pat.length();
int N = txt.length();
int i, j;
int p = 0;
int t = 0;
int h = 1;
for (i = 0; i < M - 1; i++) {
h = (h * d) % q;
}
for (i = 0; i < M; i++) {
p = (d * p + pat.charAt(i)) % q;
t = (d * t + txt.charAt(i)) % q;
}
for (i = 0; i <= N - M; i++) {
if (p == t) {
for (j = 0; j < M; j++) {
if (txt.charAt(i + j) != pat.charAt(j)) {
break;
}
}
if (j == M) {
System.out.println("Pattern found at index " + i);
}
}
if (i < N - M) {
t = (d * (t - txt.charAt(i) * h) + txt.charAt(i + 1)) % q;
if (t < 0) {
t = (t + q);
}
}
}
}
public static void main(String[] args) {
String txt = "GEEKS FOR GEEKS";
String pat = "GEEK";
search(pat, txt);
}
}
8. 数学算法
欧几里得算法 (GCD)
public class GCD {
public static int gcd(int a, int b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
public static void main(String[] args) {
int a = 56, b = 98;
System.out.println("GCD of " + a + " and " + b + " is " + gcd(a, b));
}
}
埃拉托斯特尼筛法 (Sieve of Eratosthenes)
import java.util.*;
public class SieveOfEratosthenes {
public static void sieve(int n) {
boolean[] prime = new boolean[n + 1];
Arrays.fill(prime, true);
for (int p = 2; p * p <= n; p++) {
if (prime[p]) {
for (int i = p * p; i <= n; i += p) {
prime[i] = false;
}
}
}
for (int p = 2; p <= n; p++) {
if (prime[p]) {
System.out.print(p + " ");
}
}
}
public static void main(String[] args) {
int n = 30;
System.out.println("Prime numbers less than or equal to " + n + ":");
sieve(n);
}
}
以上是一些常用的 Java 算法示例,包括排序、搜索、动态规划、贪心算法、图算法、树算法、字符串处理算法和数学算法。这些算法覆盖了许多基本且重要的编程概念和技巧,可以作为学习和参考的基础。